From 1d9dfeff6b2531ff99e0d12669b3a1dae393e768 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Thu, 19 Nov 2009 18:38:26 +0100 Subject: [PATCH] Get rid of ClientSyncer Rest in pieces, you won't be missed. --- src/client/CMakeLists.txt | 2 - src/client/clientsyncer.cpp | 435 ----------------------------------- src/client/clientsyncer.h | 124 ---------- src/qtui/mainwin.cpp | 9 +- src/qtui/monoapplication.cpp | 12 +- src/qtui/monoapplication.h | 4 +- 6 files changed, 7 insertions(+), 579 deletions(-) delete mode 100644 src/client/clientsyncer.cpp delete mode 100644 src/client/clientsyncer.h diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 31fa5d7a..dfed6925 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -22,7 +22,6 @@ set(SOURCES clientignorelistmanager.cpp clientirclisthelper.cpp clientsettings.cpp - clientsyncer.cpp clientuserinputhandler.cpp coreaccount.cpp coreaccountmodel.cpp @@ -50,7 +49,6 @@ set(MOC_HDRS clientignorelistmanager.h clientirclisthelper.h clientuserinputhandler.h - clientsyncer.h coreaccountmodel.h coreconnection.h execwrapper.h diff --git a/src/client/clientsyncer.cpp b/src/client/clientsyncer.cpp deleted file mode 100644 index 1af95b8f..00000000 --- a/src/client/clientsyncer.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * - * devel@quassel-irc.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) version 3. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include "clientsyncer.h" - -#ifndef QT_NO_NETWORKPROXY -# include -#endif - -#include "client.h" -#include "identity.h" -#include "network.h" -#include "networkmodel.h" -#include "quassel.h" -#include "signalproxy.h" -#include "util.h" - -ClientSyncer::ClientSyncer(QObject *parent) - : QObject(parent), - _socket(0), - _blockSize(0) -{ -} - -ClientSyncer::~ClientSyncer() { -} - -void ClientSyncer::coreHasData() { - QVariant item; - while(SignalProxy::readDataFromDevice(_socket, _blockSize, item)) { - emit recvPartialItem(1,1); - QVariantMap msg = item.toMap(); - if(!msg.contains("MsgType")) { - // This core is way too old and does not even speak our init protocol... - emit connectionError(tr("The Quassel Core you try to connect to is too old! Please consider upgrading.")); - disconnectFromCore(); - return; - } - if(msg["MsgType"] == "ClientInitAck") { - clientInitAck(msg); - } else if(msg["MsgType"] == "ClientInitReject") { - emit connectionError(msg["Error"].toString()); - disconnectFromCore(); - return; - } else if(msg["MsgType"] == "CoreSetupAck") { - emit coreSetupSuccess(); - } else if(msg["MsgType"] == "CoreSetupReject") { - emit coreSetupFailed(msg["Error"].toString()); - } else if(msg["MsgType"] == "ClientLoginReject") { - emit loginFailed(msg["Error"].toString()); - } else if(msg["MsgType"] == "ClientLoginAck") { - // prevent multiple signal connections - disconnect(this, SIGNAL(recvPartialItem(quint32, quint32)), this, SIGNAL(sessionProgress(quint32, quint32))); - connect(this, SIGNAL(recvPartialItem(quint32, quint32)), this, SIGNAL(sessionProgress(quint32, quint32))); - emit loginSuccess(); - } else if(msg["MsgType"] == "SessionInit") { - sessionStateReceived(msg["SessionState"].toMap()); - break; // this is definitively the last message we process here! - } else { - emit connectionError(tr("Invalid data received from core!
Disconnecting.")); - disconnectFromCore(); - return; - } - } - if(_blockSize > 0) { - emit recvPartialItem(_socket->bytesAvailable(), _blockSize); - } -} - -void ClientSyncer::coreSocketError(QAbstractSocket::SocketError) { - qDebug() << "coreSocketError" << _socket << _socket->errorString(); - emit connectionError(_socket->errorString()); - resetConnection(); -} - -void ClientSyncer::disconnectFromCore() { - resetConnection(); -} - -void ClientSyncer::connectToCore(const QVariantMap &conn) { - resetConnection(); - coreConnectionInfo = conn; - - if(conn["Host"].toString().isEmpty()) { - emit connectionError(tr("No Host to connect to specified.")); - return; - } - - Q_ASSERT(!_socket); -#ifdef HAVE_SSL - QSslSocket *sock = new QSslSocket(Client::instance()); -#else - if(conn["useSsl"].toBool()) { - emit connectionError(tr("This client is built without SSL Support!
Disable the usage of SSL in the account settings.")); - return; - } - QTcpSocket *sock = new QTcpSocket(Client::instance()); -#endif - -#ifndef QT_NO_NETWORKPROXY - if(conn.contains("useProxy") && conn["useProxy"].toBool()) { - QNetworkProxy proxy((QNetworkProxy::ProxyType)conn["proxyType"].toInt(), conn["proxyHost"].toString(), conn["proxyPort"].toUInt(), conn["proxyUser"].toString(), conn["proxyPassword"].toString()); - sock->setProxy(proxy); - } -#endif - - _socket = sock; - connect(sock, SIGNAL(readyRead()), this, SLOT(coreHasData())); - connect(sock, SIGNAL(connected()), this, SLOT(coreSocketConnected())); - connect(sock, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected())); - connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(coreSocketError(QAbstractSocket::SocketError))); - connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(socketStateChanged(QAbstractSocket::SocketState))); - sock->connectToHost(conn["Host"].toString(), conn["Port"].toUInt()); -} - -void ClientSyncer::coreSocketConnected() { - //connect(this, SIGNAL(recvPartialItem(uint, uint)), this, SIGNAL(coreConnectionProgress(uint, uint))); - // Phase One: Send client info and wait for core info - - //emit coreConnectionMsg(tr("Synchronizing to core...")); - QVariantMap clientInit; - clientInit["MsgType"] = "ClientInit"; - clientInit["ClientVersion"] = Quassel::buildInfo().fancyVersionString; - clientInit["ClientDate"] = Quassel::buildInfo().buildDate; - clientInit["ProtocolVersion"] = Quassel::buildInfo().protocolVersion; - clientInit["UseSsl"] = coreConnectionInfo["useSsl"]; -#ifndef QT_NO_COMPRESS - clientInit["UseCompression"] = true; -#else - clientInit["UseCompression"] = false; -#endif - - SignalProxy::writeDataToDevice(_socket, clientInit); -} - -void ClientSyncer::useInternalCore() { - AccountId internalAccountId; - - CoreAccountSettings accountSettings; - QList knownAccounts = accountSettings.knownAccounts(); - foreach(AccountId id, knownAccounts) { - if(!id.isValid()) - continue; - QVariantMap data = accountSettings.retrieveAccountData(id); - if(data.contains("InternalAccount") && data["InternalAccount"].toBool()) { - internalAccountId = id; - break; - } - } - - if(!internalAccountId.isValid()) { - for(AccountId i = 1;; i++) { - if(!knownAccounts.contains(i)) { - internalAccountId = i; - break; - } - } - QVariantMap data; - data["InternalAccount"] = true; - accountSettings.storeAccountData(internalAccountId, data); - } - - coreConnectionInfo["AccountId"] = QVariant::fromValue(internalAccountId); - emit startInternalCore(this); - emit connectToInternalCore(Client::instance()->signalProxy()); -} - -void ClientSyncer::coreSocketDisconnected() { - emit socketDisconnected(); - resetConnection(); - // FIXME handle disconnects gracefully -} - -void ClientSyncer::clientInitAck(const QVariantMap &msg) { - // Core has accepted our version info and sent its own. Let's see if we accept it as well... - uint ver = msg["ProtocolVersion"].toUInt(); - if(ver < Quassel::buildInfo().clientNeedsProtocol) { - emit connectionError(tr("The Quassel Core you are trying to connect to is too old!
" - "Need at least core/client protocol v%1 to connect.").arg(Quassel::buildInfo().clientNeedsProtocol)); - disconnectFromCore(); - return; - } - emit connectionMsg(coreInfoString(msg)); - -#ifndef QT_NO_COMPRESS - if(msg["SupportsCompression"].toBool()) { - _socket->setProperty("UseCompression", true); - } -#endif - - _coreMsgBuffer = msg; -#ifdef HAVE_SSL - if(coreConnectionInfo["useSsl"].toBool()) { - if(msg["SupportSsl"].toBool()) { - QSslSocket *sslSocket = qobject_cast(_socket); - Q_ASSERT(sslSocket); - connect(sslSocket, SIGNAL(encrypted()), this, SLOT(sslSocketEncrypted())); - connect(sslSocket, SIGNAL(sslErrors(const QList &)), this, SLOT(sslErrors(const QList &))); - - sslSocket->startClientEncryption(); - } else { - emit connectionError(tr("The Quassel Core you are trying to connect to does not support SSL!
If you want to connect anyways, disable the usage of SSL in the account settings.")); - disconnectFromCore(); - } - return; - } -#endif - // if we use SSL we wait for the next step until every SSL warning has been cleared - connectionReady(); -} - -void ClientSyncer::connectionReady() { - if(!_coreMsgBuffer["Configured"].toBool()) { - // start wizard - emit startCoreSetup(_coreMsgBuffer["StorageBackends"].toList()); - } else if(_coreMsgBuffer["LoginEnabled"].toBool()) { - emit startLogin(); - } - _coreMsgBuffer.clear(); - resetWarningsHandler(); -} - -void ClientSyncer::doCoreSetup(const QVariant &setupData) { - QVariantMap setup; - setup["MsgType"] = "CoreSetupData"; - setup["SetupData"] = setupData; - SignalProxy::writeDataToDevice(_socket, setup); -} - -void ClientSyncer::loginToCore(const QString &user, const QString &passwd) { - emit connectionMsg(tr("Logging in...")); - QVariantMap clientLogin; - clientLogin["MsgType"] = "ClientLogin"; - clientLogin["User"] = user; - clientLogin["Password"] = passwd; - SignalProxy::writeDataToDevice(_socket, clientLogin); -} - -void ClientSyncer::internalSessionStateReceived(const QVariant &packedState) { - QVariantMap state = packedState.toMap(); - emit sessionProgress(1, 1); - Client::instance()->setConnectedToCore(coreConnectionInfo["AccountId"].value()); - syncToCore(state); -} - -void ClientSyncer::sessionStateReceived(const QVariantMap &state) { - emit sessionProgress(1, 1); - disconnect(this, SIGNAL(recvPartialItem(quint32, quint32)), this, SIGNAL(sessionProgress(quint32, quint32))); - - // rest of communication happens through SignalProxy... - disconnect(_socket, 0, this, 0); - // ... but we still want to be notified about errors... - connect(_socket, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected())); - connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(coreSocketError(QAbstractSocket::SocketError))); - - Client::instance()->setConnectedToCore(coreConnectionInfo["AccountId"].value(), _socket); - syncToCore(state); -} - -void ClientSyncer::syncToCore(const QVariantMap &sessionState) { - // create identities - foreach(QVariant vid, sessionState["Identities"].toList()) { - Client::instance()->coreIdentityCreated(vid.value()); - } - - // create buffers - // FIXME: get rid of this crap - QVariantList bufferinfos = sessionState["BufferInfos"].toList(); - NetworkModel *networkModel = Client::networkModel(); - Q_ASSERT(networkModel); - foreach(QVariant vinfo, bufferinfos) - networkModel->bufferUpdated(vinfo.value()); // create BufferItems - - QVariantList networkids = sessionState["NetworkIds"].toList(); - - // prepare sync progress thingys... - // FIXME: Care about removal of networks - numNetsToSync = networkids.count(); - emit networksProgress(0, numNetsToSync); - - // create network objects - foreach(QVariant networkid, networkids) { - NetworkId netid = networkid.value(); - if(Client::network(netid)) - continue; - Network *net = new Network(netid, Client::instance()); - netsToSync.insert(net); - connect(net, SIGNAL(initDone()), this, SLOT(networkInitDone())); - Client::addNetwork(net); - } - checkSyncState(); -} - -void ClientSyncer::networkInitDone() { - netsToSync.remove(sender()); - emit networksProgress(numNetsToSync - netsToSync.count(), numNetsToSync); - checkSyncState(); -} - -void ClientSyncer::checkSyncState() { - if(netsToSync.isEmpty()) { - Client::instance()->setSyncedToCore(); - emit syncFinished(); - } -} - -void ClientSyncer::setWarningsHandler(const char *slot) { - resetWarningsHandler(); - connect(this, SIGNAL(handleIgnoreWarnings(bool)), this, slot); -} - -void ClientSyncer::resetWarningsHandler() { - disconnect(this, SIGNAL(handleIgnoreWarnings(bool)), this, 0); -} - -void ClientSyncer::resetConnection() { - if(_socket) { - disconnect(_socket, 0, this, 0); - _socket->deleteLater(); - _socket = 0; - } - _blockSize = 0; - - coreConnectionInfo.clear(); - _coreMsgBuffer.clear(); - - netsToSync.clear(); - numNetsToSync = 0; -} - -QString ClientSyncer::coreInfoString(const QVariantMap &coreData) { - // check if we use a new enough core - // FIXME: this can go away after v11 protocol bump - if(!coreData.contains("CoreStartTime")) - return coreData.value("CoreInfo").toString(); - - QDateTime startTime = coreData.value("CoreStartTime").toDateTime().toLocalTime(); - int uptime = startTime.secsTo(QDateTime::currentDateTime()); - int updays = uptime / 86400; uptime %= 86400; - int uphours = uptime / 3600; uptime %= 3600; - int upmins = uptime / 60; uptime %= 60; - - QString reply = tr("Quassel Core Version %1
" - "Built: %2
" - "Up %3d%4h%5m (since %6)") - .arg(coreData.value("CoreVersion").toString()) - .arg(coreData.value("CoreDate").toString()) - .arg(updays).arg(uphours,2,10,QChar('0')).arg(upmins,2,10,QChar('0')).arg(startTime.toString(Qt::TextDate)); - - return reply; -} - -#ifdef HAVE_SSL -void ClientSyncer::ignoreSslWarnings(bool permanently) { - QSslSocket *sock = qobject_cast(_socket); - if(sock) { - // ensure that a proper state is displayed and no longer a warning - emit socketStateChanged(sock->state()); - } - if(permanently) { - if(!sock) - qWarning() << Q_FUNC_INFO << "unable to save cert digest! Socket is either a nullptr or not a QSslSocket"; - else - KnownHostsSettings().saveKnownHost(sock); - } - emit connectionMsg(coreInfoString(_coreMsgBuffer)); - connectionReady(); -} - -void ClientSyncer::sslSocketEncrypted() { - QSslSocket *socket = qobject_cast(sender()); - Q_ASSERT(socket); - - // if there were sslErrors we already had extensive error handling - // no need to check for a digest change again. - if(!socket->sslErrors().isEmpty()) - return; - - QByteArray knownDigest = KnownHostsSettings().knownDigest(socket); - if(knownDigest == socket->peerCertificate().digest()) { - connectionReady(); - return; - } - - QStringList warnings; - if(!knownDigest.isEmpty()) { - warnings << tr("Cert Digest changed! was: %1").arg(QString(prettyDigest(knownDigest))); - } - - setWarningsHandler(SLOT(ignoreSslWarnings(bool))); - emit connectionWarnings(warnings); -} - -void ClientSyncer::sslErrors(const QList &errors) { - QSslSocket *socket = qobject_cast(sender()); - Q_ASSERT(socket); - - socket->ignoreSslErrors(); - - QByteArray knownDigest = KnownHostsSettings().knownDigest(socket); - if(knownDigest == socket->peerCertificate().digest()) { - connectionReady(); - return; - } - - QStringList warnings; - - foreach(QSslError err, errors) - warnings << err.errorString(); - - if(!knownDigest.isEmpty()) { - warnings << tr("Cert Digest changed! was: %1").arg(QString(prettyDigest(knownDigest))); - } - - setWarningsHandler(SLOT(ignoreSslWarnings(bool))); - emit connectionWarnings(warnings); -} -#endif diff --git a/src/client/clientsyncer.h b/src/client/clientsyncer.h deleted file mode 100644 index 8689279c..00000000 --- a/src/client/clientsyncer.h +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * - * devel@quassel-irc.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) version 3. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#ifndef CLIENTSYNCER_H_ -#define CLIENTSYNCER_H_ - -#include -#include -#include - -#ifdef HAVE_SSL -# include -#else -# include -#endif - -#include "types.h" - -class IrcUser; -class IrcChannel; -class SignalProxy; - -class ClientSyncer : public QObject { - Q_OBJECT - -public: - ClientSyncer(QObject *parent = 0); - ~ClientSyncer(); - - inline const QIODevice *currentDevice() { return _socket; } - -signals: - void recvPartialItem(quint32 avail, quint32 size); - void connectionError(const QString &errorMsg); - void connectionWarnings(const QStringList &warnings); - void connectionMsg(const QString &msg); - void sessionProgress(quint32 part, quint32 total); - void networksProgress(quint32 part, quint32 total); - void socketStateChanged(QAbstractSocket::SocketState); - void socketDisconnected(); - - void startLogin(); - void loginFailed(const QString &error); - void loginSuccess(); - void syncFinished(); - void startCoreSetup(const QVariantList &); - void coreSetupSuccess(); - void coreSetupFailed(const QString &error); - - void encrypted(); // relaying encrypted signal of the encapsulated SslSocket - - void startInternalCore(ClientSyncer *syncer); - void connectToInternalCore(SignalProxy *proxy); - - void handleIgnoreWarnings(bool permanently); - -public slots: - void connectToCore(const QVariantMap &); - void loginToCore(const QString &user, const QString &passwd); - void disconnectFromCore(); - void useInternalCore(); - - inline void ignoreWarnings(bool permanently) { emit handleIgnoreWarnings(permanently); } - -private slots: - void coreSocketError(QAbstractSocket::SocketError); - void coreHasData(); - void coreSocketConnected(); - void coreSocketDisconnected(); - - void clientInitAck(const QVariantMap &msg); - - // for sync progress - void networkInitDone(); - void checkSyncState(); - - void syncToCore(const QVariantMap &sessionState); - void internalSessionStateReceived(const QVariant &packedState); - void sessionStateReceived(const QVariantMap &state); - - void connectionReady(); - void doCoreSetup(const QVariant &setupData); - - void setWarningsHandler(const char *slot); - void resetWarningsHandler(); - void resetConnection(); - -#ifdef HAVE_SSL - void ignoreSslWarnings(bool permanently); - void sslSocketEncrypted(); - void sslErrors(const QList &errors); -#endif - -private: - QPointer _socket; - quint32 _blockSize; - - QVariantMap coreConnectionInfo; - QVariantMap _coreMsgBuffer; - - QSet netsToSync; - int numNetsToSync; - - QString coreInfoString(const QVariantMap &); -}; - -#endif diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 6e6b8513..94bd517f 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -815,17 +815,14 @@ void MainWin::setDisconnectedState() { sslLabel->hide(); updateLagIndicator(); coreLagLabel->hide(); - if(msgProcessorStatusWidget) - msgProcessorStatusWidget->setProgress(0, 0); + if(_msgProcessorStatusWidget) + _msgProcessorStatusWidget->setProgress(0, 0); updateIcon(); systemTray()->setState(SystemTray::Inactive); } void MainWin::startInternalCore() { - ClientSyncer *syncer = new ClientSyncer(); - Client::registerClientSyncer(syncer); - connect(syncer, SIGNAL(syncFinished()), syncer, SLOT(deleteLater()), Qt::QueuedConnection); - syncer->useInternalCore(); + } void MainWin::showChannelList(NetworkId netId) { diff --git a/src/qtui/monoapplication.cpp b/src/qtui/monoapplication.cpp index 216601aa..60df4c5b 100644 --- a/src/qtui/monoapplication.cpp +++ b/src/qtui/monoapplication.cpp @@ -21,7 +21,6 @@ #include "monoapplication.h" #include "coreapplication.h" #include "client.h" -#include "clientsyncer.h" #include "core.h" #include "qtui.h" @@ -45,7 +44,6 @@ bool MonolithicApplication::init() { _internalInitDone = true; } - connect(Client::instance(), SIGNAL(newClientSyncer(ClientSyncer *)), this, SLOT(newClientSyncer(ClientSyncer *))); return QtUiApplication::init(); } @@ -55,16 +53,12 @@ MonolithicApplication::~MonolithicApplication() { delete _internal; } -void MonolithicApplication::newClientSyncer(ClientSyncer *syncer) { - connect(syncer, SIGNAL(startInternalCore(ClientSyncer *)), this, SLOT(startInternalCore(ClientSyncer *))); -} - -void MonolithicApplication::startInternalCore(ClientSyncer *syncer) { +void MonolithicApplication::startInternalCore() { if(!_internalInitDone) { _internal->init(); _internalInitDone = true; } Core *core = Core::instance(); - connect(syncer, SIGNAL(connectToInternalCore(SignalProxy *)), core, SLOT(setupInternalClientSession(SignalProxy *))); - connect(core, SIGNAL(sessionState(const QVariant &)), syncer, SLOT(internalSessionStateReceived(const QVariant &))); + //connect(syncer, SIGNAL(connectToInternalCore(SignalProxy *)), core, SLOT(setupInternalClientSession(SignalProxy *))); + //connect(core, SIGNAL(sessionState(const QVariant &)), syncer, SLOT(internalSessionStateReceived(const QVariant &))); } diff --git a/src/qtui/monoapplication.h b/src/qtui/monoapplication.h index de7963ec..086bb473 100644 --- a/src/qtui/monoapplication.h +++ b/src/qtui/monoapplication.h @@ -23,7 +23,6 @@ #include "qtuiapplication.h" -class ClientSyncer; class CoreApplicationInternal; class MonolithicApplication : public QtUiApplication { @@ -35,8 +34,7 @@ public: bool init(); private slots: - void newClientSyncer(ClientSyncer *syncer); - void startInternalCore(ClientSyncer *syncer); + void startInternalCore(); private: CoreApplicationInternal *_internal; -- 2.20.1