⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3ftp.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	p |= QUrlInfo::WriteGroup;    if ( perms[ group ][ executable ] )	p |= QUrlInfo::ExeGroup;    if ( perms[ other ][ readable ] )	p |= QUrlInfo::ReadOther;    if ( perms[ other ][ writable ] )	p |= QUrlInfo::WriteOther;    if ( perms[ other ][ executable ] )	p |= QUrlInfo::ExeOther;    info->setPermissions( p );    // size    tmp = lst[ 4 ];    info->setSize( tmp.toInt() );    // date and time    QTime time;    QString dateStr;    dateStr += QLatin1String("Sun ");    lst[ 5 ][ 0 ] = lst[ 5 ][ 0 ].upper();    dateStr += lst[ 5 ];    dateStr += QLatin1Char(' ');    dateStr += lst[ 6 ];    dateStr += QLatin1Char(' ');    if ( lst[ 7 ].contains( QLatin1String(":") ) ) {	time = QTime( lst[ 7 ].left( 2 ).toInt(), lst[ 7 ].right( 2 ).toInt() );	dateStr += QString::number( QDate::currentDate().year() );    } else {	dateStr += lst[ 7 ];    }    QDate date = QDate::fromString( dateStr );    info->setLastModified( QDateTime( date, time ) );    if ( lst[ 7 ].contains( QLatin1String(":") ) ) {	const int futureTolerance = 600;	if( info->lastModified().secsTo( QDateTime::currentDateTime() ) < -futureTolerance ) {	    QDateTime dt = info->lastModified();	    QDate d = dt.date();	    d.setYMD(d.year()-1, d.month(), d.day());	    dt.setDate(d);	    info->setLastModified(dt);	}    }    // name    if ( info->isSymLink() )	info->setName( lst[ 8 ].stripWhiteSpace() );    else {	QString n;	for ( uint i = 8; i < (uint) lst.count(); ++i )	    n += lst[ i ] + QLatin1String(" ");	n = n.stripWhiteSpace();	info->setName( n );    }    return true;}void Q3FtpDTP::socketConnected(){#if !defined (Q_WS_QWS)    // Use a large send buffer to reduce the number    // of writeBlocks when download and uploading files.    // The actual size used here (128k) is default on most    // Unixes.    socket.socketDevice()->setSendBufferSize(128 * 1024);    socket.socketDevice()->setReceiveBufferSize(128 * 1024);#endif    bytesDone = 0;#if defined(Q3FTPDTP_DEBUG)    qDebug( "Q3FtpDTP::connectState( CsConnected )" );#endif    emit connectState( Q3FtpDTP::CsConnected );}void Q3FtpDTP::socketReadyRead(){    if ( pi->currentCommand().isEmpty() ) {	socket.close();#if defined(Q3FTPDTP_DEBUG)	qDebug( "Q3FtpDTP::connectState( CsClosed )" );#endif	emit connectState( Q3FtpDTP::CsClosed );	return;    }    if ( pi->currentCommand().startsWith(QLatin1String("LIST")) ) {	while ( socket.canReadLine() ) {	    QUrlInfo i;	    QString line = QLatin1String(socket.readLine());#if defined(Q3FTPDTP_DEBUG)	    qDebug( "Q3FtpDTP read (list): '%s'", line.latin1() );#endif	    if ( parseDir( line, QLatin1String(""), &i ) ) {		emit listInfo( i );	    } else {		// some FTP servers don't return a 550 if the file or directory		// does not exist, but rather write a text to the data socket		// -- try to catch these cases		if ( line.endsWith( QLatin1String("No such file or directory\r\n") ) )		    err = line;	    }	}    } else {	if ( !is_ba && data.dev ) {	    QByteArray ba( socket.bytesAvailable() );	    Q_LONG bytesRead = socket.readBlock( ba.data(), ba.size() );	    if ( bytesRead < 0 ) {		// ### error handling		return;	    }	    ba.resize( bytesRead );	    bytesDone += bytesRead;#if defined(Q3FTPDTP_DEBUG)	    qDebug( "Q3FtpDTP read: %d bytes (total %d bytes)", (int)bytesRead, bytesDone );#endif	    emit dataTransferProgress( bytesDone, bytesTotal );            if (data.dev)       // make sure it wasn't deleted in the slot                data.dev->writeBlock( ba );	} else {#if defined(Q3FTPDTP_DEBUG)	    qDebug( "Q3FtpDTP readyRead: %d bytes available (total %d bytes read)", (int)bytesAvailable(), bytesDone );#endif	    emit dataTransferProgress( bytesDone+socket.bytesAvailable(), bytesTotal );	    emit readyRead();	}    }}void Q3FtpDTP::socketError( int e ){    if ( e == Q3Socket::ErrHostNotFound ) {#if defined(Q3FTPDTP_DEBUG)	qDebug( "Q3FtpDTP::connectState( CsHostNotFound )" );#endif	emit connectState( Q3FtpDTP::CsHostNotFound );    } else if ( e == Q3Socket::ErrConnectionRefused ) {#if defined(Q3FTPDTP_DEBUG)	qDebug( "Q3FtpDTP::connectState( CsConnectionRefused )" );#endif	emit connectState( Q3FtpDTP::CsConnectionRefused );    }}void Q3FtpDTP::socketConnectionClosed(){    if ( !is_ba && data.dev ) {	clearData();    }#if defined(Q3FTPDTP_DEBUG)    qDebug( "Q3FtpDTP::connectState( CsClosed )" );#endif    emit connectState( Q3FtpDTP::CsClosed );}void Q3FtpDTP::socketBytesWritten( int bytes ){    bytesDone += bytes;#if defined(Q3FTPDTP_DEBUG)    qDebug( "Q3FtpDTP::bytesWritten( %d )", bytesDone );#endif    emit dataTransferProgress( bytesDone, bytesTotal );    if ( callWriteData )	writeData();}/********************************************************************** * * Q3FtpPI implemenatation * *********************************************************************/Q3FtpPI::Q3FtpPI( QObject *parent ) :    QObject( parent ),    rawCommand(false),    dtp( this ),    commandSocket( 0, "Q3FtpPI_socket" ),    state( Begin ), abortState( None ),    currentCmd( QString() ),    waitForDtpToConnect( false ),    waitForDtpToClose( false ){    connect( &commandSocket, SIGNAL(hostFound()),	    SLOT(hostFound()) );    connect( &commandSocket, SIGNAL(connected()),	    SLOT(connected()) );    connect( &commandSocket, SIGNAL(connectionClosed()),	    SLOT(connectionClosed()) );    connect( &commandSocket, SIGNAL(delayedCloseFinished()),	    SLOT(delayedCloseFinished()) );    connect( &commandSocket, SIGNAL(readyRead()),	    SLOT(readyRead()) );    connect( &commandSocket, SIGNAL(error(int)),	    SLOT(error(int)) );    connect( &dtp, SIGNAL(connectState(int)),	     SLOT(dtpConnectState(int)) );}void Q3FtpPI::connectToHost( const QString &host, Q_UINT16 port ){    emit connectState( Q3Ftp::HostLookup );    commandSocket.connectToHost( host, port );}/*  Sends the sequence of commands \a cmds to the FTP server. When the commands  are all done the finished() signal is emitted. When an error occurs, the  error() signal is emitted.  If there are pending commands in the queue this functions returns false and  the \a cmds are not added to the queue; otherwise it returns true.*/bool Q3FtpPI::sendCommands( const QStringList &cmds ){    if ( !pendingCommands.isEmpty() )	return false;    if ( commandSocket.state()!=Q3Socket::Connected || state!=Idle ) {	emit error( Q3Ftp::NotConnected, QFtp::tr( "Not connected" ) );	return true; // there are no pending commands    }    pendingCommands = cmds;    startNextCmd();    return true;}void Q3FtpPI::clearPendingCommands(){    pendingCommands.clear();    dtp.abortConnection();    currentCmd.clear();    state = Idle;}void Q3FtpPI::abort(){    pendingCommands.clear();    if ( abortState != None )	// ABOR already sent	return;    abortState = AbortStarted;#if defined(Q3FTPPI_DEBUG)    qDebug( "Q3FtpPI send: ABOR" );#endif    commandSocket.writeBlock( "ABOR\r\n", 6 );    if ( currentCmd.startsWith(QLatin1String("STOR ")) )	dtp.abortConnection();}void Q3FtpPI::hostFound(){    emit connectState( Q3Ftp::Connecting );}void Q3FtpPI::connected(){    state = Begin;#if defined(Q3FTPPI_DEBUG)//    qDebug( "Q3FtpPI state: %d [connected()]", state );#endif    emit connectState( Q3Ftp::Connected );}void Q3FtpPI::connectionClosed(){    commandSocket.close();    emit connectState( Q3Ftp::Unconnected );}void Q3FtpPI::delayedCloseFinished(){    emit connectState( Q3Ftp::Unconnected );}void Q3FtpPI::error( int e ){    if ( e == Q3Socket::ErrHostNotFound ) {	emit connectState( Q3Ftp::Unconnected );	emit error( Q3Ftp::HostNotFound,		    QFtp::tr( "Host %1 not found" ).arg( commandSocket.peerName() ) );    } else if ( e == Q3Socket::ErrConnectionRefused ) {	emit connectState( Q3Ftp::Unconnected );	emit error( Q3Ftp::ConnectionRefused,		    QFtp::tr( "Connection refused to host %1" ).arg( commandSocket.peerName() ) );    }}void Q3FtpPI::readyRead(){    if ( waitForDtpToClose )	return;    while ( commandSocket.canReadLine() ) {	// read line with respect to line continuation	QString line = QLatin1String(commandSocket.readLine());	if ( replyText.isEmpty() ) {	    if ( line.length() < 3 ) {		// ### protocol error		return;	    }	    const int lowerLimit[3] = {1,0,0};	    const int upperLimit[3] = {5,5,9};	    for ( int i=0; i<3; i++ ) {		replyCode[i] = line[i].digitValue();		if ( replyCode[i]<lowerLimit[i] || replyCode[i]>upperLimit[i] ) {		    // ### protocol error		    return;		}	    }	}	QString endOfMultiLine;	endOfMultiLine[0] = '0' + replyCode[0];	endOfMultiLine[1] = '0' + replyCode[1];	endOfMultiLine[2] = '0' + replyCode[2];	endOfMultiLine[3] = ' ';	QString lineCont( endOfMultiLine );	lineCont[3] = '-';	QString lineLeft4 = line.left(4);	while ( lineLeft4 != endOfMultiLine ) {	    if ( lineLeft4 == lineCont )		replyText += line.mid( 4 ); // strip 'xyz-'	    else		replyText += line;	    if ( !commandSocket.canReadLine() )		return;	    line = QLatin1String(commandSocket.readLine());	    lineLeft4 = line.left(4);	}	replyText += line.mid( 4 ); // strip reply code 'xyz '	if ( replyText.endsWith(QLatin1String("\r\n")) )	    replyText.truncate( replyText.length()-2 );	if ( processReply() )	    replyText = QLatin1String("");    }}/*  Process a reply from the FTP server.  Returns true if the reply was processed or false if the reply has to be  processed at a later point.*/bool Q3FtpPI::processReply(){#if defined(Q3FTPPI_DEBUG)//    qDebug( "Q3FtpPI state: %d [processReply() begin]", state );    if ( replyText.length() < 400 )	qDebug( "Q3FtpPI recv: %d %s", 100*replyCode[0]+10*replyCode[1]+replyCode[2], replyText.latin1() );    else	qDebug( "Q3FtpPI recv: %d (text skipped)", 100*replyCode[0]+10*replyCode[1]+replyCode[2] );#endif    // process 226 replies ("Closing Data Connection") only when the data    // connection is really closed to avoid short reads of the DTP    if ( 100*replyCode[0]+10*replyCode[1]+replyCode[2] == 226 ) {	if ( dtp.socketState() != Q3Socket::Idle ) {	    waitForDtpToClose = true;	    return false;	}    }    switch ( abortState ) {	case AbortStarted:	    abortState = WaitForAbortToFinish;	    break;	case WaitForAbortToFinish:	    abortState = None;	    return true;	default:	    break;    }    // get new state    static const State table[5] = {	/* 1yz   2yz      3yz   4yz      5yz */	Waiting, Success, Idle, Failure, Failure    };    switch ( state ) {	case Begin:	    if ( replyCode[0] == 1 ) {		return true;	    } else if ( replyCode[0] == 2 ) {		state = Idle;		emit finished( QFtp::tr( "Connected to host %1" ).arg( commandSocket.peerName() ) );		break;	    }	    // ### error handling	    return true;	case Waiting:	    if ( replyCode[0]<0 || replyCode[0]>5 )		state = Failure;	    else#if defined(Q_OS_IRIX) && defined(Q_CC_GNU)            {                // work around a crash on 64 bit gcc IRIX                State *t = (State *) table;                state = t[replyCode[0] - 1];            }#else            state = table[replyCode[0] - 1];#endif	    break;	default:	    // ### spontaneous message	    return true;    }#if defined(Q3FTPPI_DEBUG)//    qDebug( "Q3FtpPI state: %d [processReply() intermediate]", state );#endif    // special actions on certain replies    int replyCodeInt = 100*replyCode[0] + 10*replyCode[1] + replyCode[2];    emit rawFtpReply( replyCodeInt, replyText );    if ( rawCommand ) {	rawCommand = false;    } else if ( replyCodeInt == 227 ) {	// 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)        // rfc959 does not define this response precisely, and gives        // both examples where the parenthesis are used, and where        // they are missing. We need to scan for the address and host        // info.	QRegExp addrPortPattern(QLatin1String("(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)"));	if (addrPortPattern.search(replyText) == -1) {#if defined(Q3FTPPI_DEBUG)	    qDebug( "Q3Ftp: bad 227 response -- address and port information missing" );#endif	    // ### error handling	} else {	    QStringList lst = addrPortPattern.capturedTexts();	    QString host = lst[1] + QLatin1String(".") + lst[2] + QLatin1String(".") + lst[3] + QLatin1String(".") + lst[4];	    Q_UINT16 port = ( lst[5].toUInt() << 8 ) + lst[6].toUInt();	    waitForDtpToConnect = true;	    dtp.connectToHost( host, port );	}    } else if ( replyCodeInt == 230 ) {	if ( currentCmd.startsWith(QLatin1String("USER ")) && pendingCommands.count()>0 &&		pendingCommands.first().startsWith(QLatin1String("PASS ")) ) {	    // no need to send the PASS -- we are already logged in	    pendingCommands.pop_front();	}	// 230 User logged in, proceed.	emit connectState( Q3Ftp::LoggedIn );    } else if ( replyCodeInt == 213 ) {	// 213 File status.	if ( currentCmd.startsWith(QLatin1String("SIZE ")) )	    dtp.setBytesTotal( replyText.simplifyWhiteSpace().toInt() );    } else if ( replyCode[0]==1 && currentCmd.startsWith(QLatin1String("STOR ")) ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -