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

📄 qftp.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}void QFtpPI::clearPendingCommands(){    pendingCommands.clear();    dtp.abortConnection();    currentCmd.clear();    state = Idle;}void QFtpPI::abort(){    pendingCommands.clear();    if (abortState != None)        // ABOR already sent        return;    abortState = AbortStarted;#if defined(QFTPPI_DEBUG)    qDebug("QFtpPI send: ABOR");#endif    commandSocket.write("ABOR\r\n", 6);    if (currentCmd.startsWith(QLatin1String("STOR ")))        dtp.abortConnection();}void QFtpPI::hostFound(){    emit connectState(QFtp::Connecting);}void QFtpPI::connected(){    state = Begin;#if defined(QFTPPI_DEBUG)//    qDebug("QFtpPI state: %d [connected()]", state);#endif    emit connectState(QFtp::Connected);}void QFtpPI::connectionClosed(){    commandSocket.close();    emit connectState(QFtp::Unconnected);}void QFtpPI::delayedCloseFinished(){    emit connectState(QFtp::Unconnected);}void QFtpPI::error(QAbstractSocket::SocketError e){    if (e == QTcpSocket::HostNotFoundError) {        emit connectState(QFtp::Unconnected);        emit error(QFtp::HostNotFound,                    QFtp::tr("Host %1 not found").arg(commandSocket.peerName()));    } else if (e == QTcpSocket::ConnectionRefusedError) {        emit connectState(QFtp::Unconnected);        emit error(QFtp::ConnectionRefused,                    QFtp::tr("Connection refused to host %1").arg(commandSocket.peerName()));    }}void QFtpPI::readyRead(){    if (waitForDtpToClose)        return;    while (commandSocket.canReadLine()) {        // read line with respect to line continuation        QString line = QString::fromAscii(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] = QLatin1Char(' ');        QString lineCont(endOfMultiLine);        lineCont[3] = QLatin1Char('-');        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 = QString::fromAscii(commandSocket.readLine());            lineLeft4 = line.left(4);        }        replyText += line.mid(4); // strip reply code 'xyz '        if (replyText.endsWith(QLatin1String("\r\n")))            replyText.chop(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 QFtpPI::processReply(){#if defined(QFTPPI_DEBUG)//    qDebug("QFtpPI state: %d [processReply() begin]", state);    if (replyText.length() < 400)        qDebug("QFtpPI recv: %d %s", 100*replyCode[0]+10*replyCode[1]+replyCode[2], replyText.toLatin1().constData());    else        qDebug("QFtpPI recv: %d (text skipped)", 100*replyCode[0]+10*replyCode[1]+replyCode[2]);#endif    int replyCodeInt = 100*replyCode[0] + 10*replyCode[1] + replyCode[2];    // process 226 replies ("Closing Data Connection") only when the data    // connection is really closed to avoid short reads of the DTP    if (replyCodeInt == 226 || (replyCodeInt == 250 && currentCmd.startsWith(QLatin1String("RETR")))) {        if (dtp.state() != QTcpSocket::UnconnectedState) {            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;            }            // reply codes not starting with 1 or 2 are not handled.            return true;        case Waiting:            if (static_cast<signed char>(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            if (replyCodeInt == 202)                state = Failure;            else                state = table[replyCode[0] - 1];#endif            break;        default:            // ignore unrequested message            return true;    }#if defined(QFTPPI_DEBUG)//    qDebug("QFtpPI state: %d [processReply() intermediate]", state);#endif    // special actions on certain replies    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.indexIn(replyText) == -1) {#if defined(QFTPPI_DEBUG)            qDebug("QFtp: bad 227 response -- address and port information missing");#endif            // this error should be reported        } else {            QStringList lst = addrPortPattern.capturedTexts();            QString host = lst[1] + QLatin1Char('.') + lst[2] + QLatin1Char('.') + lst[3] + QLatin1Char('.') + lst[4];            quint16 port = (lst[5].toUInt() << 8) + lst[6].toUInt();            waitForDtpToConnect = true;            dtp.connectToHost(host, port);        }    } else if (replyCodeInt == 229) {        // 229 Extended Passive mode OK (|||10982|)        int portPos = replyText.indexOf(QLatin1Char('('));        if (portPos == -1) {#if defined(QFTPPI_DEBUG)            qDebug("QFtp: bad 229 response -- port information missing");#endif            // this error should be reported        } else {            ++portPos;            QChar delimiter = replyText.at(portPos);            QStringList epsvParameters = replyText.mid(portPos).split(delimiter);            waitForDtpToConnect = true;            dtp.connectToHost(commandSocket.peerAddress().toString(),                              epsvParameters.at(3).toInt());        }    } 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(QFtp::LoggedIn);    } else if (replyCodeInt == 213) {        // 213 File status.        if (currentCmd.startsWith(QLatin1String("SIZE ")))            dtp.setBytesTotal(replyText.simplified().toLongLong());    } else if (replyCode[0]==1 && currentCmd.startsWith(QLatin1String("STOR "))) {        dtp.waitForConnection();        dtp.writeData();    }    // react on new state    switch (state) {        case Begin:            // should never happen            break;        case Success:            // success handling            state = Idle;            // no break!        case Idle:            if (dtp.hasError()) {                emit error(QFtp::UnknownError, dtp.errorMessage());                dtp.clearError();            }            startNextCmd();            break;        case Waiting:            // do nothing            break;        case Failure:            // If the EPSV or EPRT commands fail, replace them with            // the old PASV and PORT instead and try again.            if (currentCmd.startsWith(QLatin1String("EPSV"))) {                transferConnectionExtended = false;                pendingCommands.prepend(QLatin1String("PASV\r\n"));            } else if (currentCmd.startsWith(QLatin1String("EPRT"))) {                transferConnectionExtended = false;                pendingCommands.prepend(QLatin1String("PORT\r\n"));            } else {                emit error(QFtp::UnknownError, replyText);            }            if (state != Waiting) {                state = Idle;                startNextCmd();            }            break;    }#if defined(QFTPPI_DEBUG)//    qDebug("QFtpPI state: %d [processReply() end]", state);#endif    return true;}/*  Starts next pending command. Returns false if there are no pending commands,  otherwise it returns true.*/bool QFtpPI::startNextCmd(){    if (waitForDtpToConnect)        // don't process any new commands until we are connected        return true;#if defined(QFTPPI_DEBUG)    if (state != Idle)        qDebug("QFtpPI startNextCmd: Internal error! QFtpPI called in non-Idle state %d", state);#endif    if (pendingCommands.isEmpty()) {        currentCmd.clear();        emit finished(replyText);        return false;    }    currentCmd = pendingCommands.first();    // PORT and PASV are edited in-place, depending on whether we    // should try the extended transfer connection commands EPRT and    // EPSV. The PORT command also triggers setting up a listener, and    // the address/port arguments are edited in.    QHostAddress address = commandSocket.localAddress();    if (currentCmd.startsWith(QLatin1String("PORT"))) {        if ((address.protocol() == QTcpSocket::IPv6Protocol) && transferConnectionExtended) {            int port = dtp.setupListener(address);            currentCmd = QLatin1String("EPRT |");            currentCmd += (address.protocol() == QTcpSocket::IPv4Protocol) ? QLatin1Char('1') : QLatin1Char('2');            currentCmd += QLatin1Char('|') + address.toString() + QLatin1Char('|') + QString::number(port);            currentCmd += QLatin1Char('|');        } else if (address.protocol() == QTcpSocket::IPv4Protocol) {            int port = dtp.setupListener(address);            QString portArg;            quint32 ip = address.toIPv4Address();            portArg += QString::number((ip & 0xff000000) >> 24);            portArg += QLatin1Char(',') + QString::number((ip & 0xff0000) >> 16);            portArg += QLatin1Char(',') + QString::number((ip & 0xff00) >> 8);            portArg += QLatin1Char(',') + QString::number(ip & 0xff);            portArg += QLatin1Char(',') + QString::number((port & 0xff00) >> 8);            portArg += QLatin1Char(',') + QString::number(port & 0xff);            currentCmd = QLatin1String("PORT ");            currentCmd += portArg;        } else {            // No IPv6 connection can be set up with the PORT            // command.            return false;        }        currentCmd += QLatin1String("\r\n");    } else if (currentCmd.startsWith(QLatin1String("PASV"))) {        if ((address.protocol() == QTcpSocket::IPv6Protocol) && transferConnectionExtended)            currentCmd = QLatin1String("EPSV\r\n");    }    pendingCommands.pop_front();#if defined(QFTPPI_DEBUG)    qDebug("QFtpPI send: %s", currentCmd.left(currentCmd.length()-2).toLatin1().constData());#endif    state = Waiting;    commandSocket.write(currentCmd.toLatin1());    return true;}void QFtpPI::dtpConnectState(int s){    switch (s) {        case QFtpDTP::CsClosed:            if (waitForDtpToClose) {                // there is an unprocessed reply                if (processReply())                    replyText = QLatin1String("");                else                    return;            }            waitForDtpToClose = false;            readyRead();            return;        case QFtpDTP::CsConnected:            waitForDtpToConnect = false;            startNextCmd();            return;        case QFtpDTP::CsHostNotFound:        case QFtpDTP::CsConnectionRefused:            emit error(QFtp::ConnectionRefused,                        QFtp::tr("Connection refused for data connection"));            startNextCmd();            return;        default:            return;    }}/********************************************************************** * * QFtpPrivate * *********************************************************************/#include <private/qobject_p.h>class QFtpPrivate : public QObjectPrivate{    Q_DECLARE_PUBLIC(QFtp)public:    inline QFtpPrivate() : close_waitForStateChange(false), state(QFtp::Unconnected),                           transferMode(QFtp::Passive), error(QFtp::NoError)    { }

⌨️ 快捷键说明

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