1 /***************************************************************************
2 * Copyright (C) 2005-07 by The Quassel IRC Development Team *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
22 #include "coresession.h"
23 #include "sqlitestorage.h"
26 Core *Core::instanceptr = 0;
28 Core *Core::instance() {
29 if(instanceptr) return instanceptr;
30 instanceptr = new Core();
35 void Core::destroy() {
44 if(!SqliteStorage::isAvailable()) {
45 qFatal("Sqlite is currently required! Please make sure your Qt library has sqlite support enabled.");
47 //SqliteStorage::init();
48 storage = new SqliteStorage();
49 connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
50 startListening(); // FIXME make configurable
59 CoreSession *Core::session(UserId uid) {
60 Core *core = instance();
61 if(core->sessions.contains(uid)) return core->sessions[uid];
65 CoreSession *Core::localSession() {
66 Core *core = instance();
67 if(core->guiUser && core->sessions.contains(core->guiUser)) return core->sessions[core->guiUser];
71 CoreSession *Core::createSession(UserId uid) {
72 Core *core = instance();
73 Q_ASSERT(!core->sessions.contains(uid));
74 CoreSession *sess = new CoreSession(uid, core->storage);
75 core->sessions[uid] = sess;
80 bool Core::startListening(uint port) {
81 if(!server.listen(QHostAddress::Any, port)) {
82 qWarning(QString(QString("Could not open GUI client port %1: %2").arg(port).arg(server.errorString())).toAscii());
85 qDebug() << "Listening for GUI clients on port" << server.serverPort();
89 void Core::stopListening() {
91 qDebug() << "No longer listening for GUI clients.";
94 void Core::incomingConnection() {
97 QTcpSocket *socket = server.nextPendingConnection();
98 connect(socket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
99 connect(socket, SIGNAL(readyRead()), this, SLOT(clientHasData()));
100 blockSizes.insert(socket, (quint32)0);
101 qDebug() << "Client connected from " << socket->peerAddress().toString();
104 void Core::clientHasData() {
105 QTcpSocket *socket = dynamic_cast<QTcpSocket*>(sender());
106 Q_ASSERT(socket && blockSizes.contains(socket));
107 quint32 bsize = blockSizes.value(socket);
109 if(readDataFromDevice(socket, bsize, item)) {
110 // we need to auth the client
112 processClientInit(socket, item);
113 } catch(Storage::AuthError) {
114 qWarning() << "Authentification error!"; // FIXME: send auth error to client
117 } catch(Exception e) {
118 qWarning() << "Client init error:" << e.msg();
123 blockSizes[socket] = bsize = 0; // FIXME blockSizes aufräum0rn!
126 // FIXME: no longer called, since connection handling is now in SignalProxy
127 void Core::clientDisconnected() {
128 QTcpSocket *socket = dynamic_cast<QTcpSocket*>(sender());
129 blockSizes.remove(socket);
130 qDebug() << "Client disconnected.";
131 // TODO remove unneeded sessions - if necessary/possible...
134 QVariant Core::connectLocalClient(QString user, QString passwd) {
135 UserId uid = instance()->storage->validateUser(user, passwd);
136 QVariant reply = instance()->initSession(uid);
137 instance()->guiUser = uid;
138 qDebug() << "Local client connected.";
142 void Core::disconnectLocalClient() {
143 qDebug() << "Local client disconnected.";
144 instance()->guiUser = 0;
147 void Core::processClientInit(QTcpSocket *socket, const QVariant &v) {
148 QVariantMap msg = v.toMap();
149 if(msg["GuiProtocol"].toUInt() != GUI_PROTOCOL) {
150 //qWarning() << "Client version mismatch.";
151 throw Exception("GUI client version mismatch");
154 UserId uid = storage->validateUser(msg["User"].toString(), msg["Password"].toString()); // throws exception if this failed
155 QVariant reply = initSession(uid);
156 disconnect(socket, 0, this, 0);
157 sessions[uid]->addClient(socket);
158 qDebug() << "Client initialized successfully.";
159 writeDataToDevice(socket, reply);
162 QVariant Core::initSession(UserId uid) {
163 // Find or create session for validated user
165 if(sessions.contains(uid))
166 sess = sessions[uid];
168 sess = createSession(uid);
170 reply["SessionState"] = sess->sessionState();