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() {
45 if(!SqliteStorage::isAvailable()) {
46 qFatal("Sqlite is currently required! Please make sure your Qt library has sqlite support enabled.");
48 //SqliteStorage::init();
49 storage = new SqliteStorage();
50 connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
51 startListening(); // FIXME make configurable
60 CoreSession *Core::session(UserId uid) {
61 Core *core = instance();
62 if(core->sessions.contains(uid)) return core->sessions[uid];
66 CoreSession *Core::localSession() {
67 Core *core = instance();
68 if(core->guiUser && core->sessions.contains(core->guiUser)) return core->sessions[core->guiUser];
72 CoreSession *Core::createSession(UserId uid) {
73 Core *core = instance();
74 Q_ASSERT(!core->sessions.contains(uid));
75 CoreSession *sess = new CoreSession(uid, core->storage);
76 core->sessions[uid] = sess;
81 bool Core::startListening(uint port) {
82 if(!server.listen(QHostAddress::Any, port)) {
83 qWarning(QString(QString("Could not open GUI client port %1: %2").arg(port).arg(server.errorString())).toAscii());
86 qDebug() << "Listening for GUI clients on port" << server.serverPort();
90 void Core::stopListening() {
92 qDebug() << "No longer listening for GUI clients.";
95 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
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 writeDataToDevice(socket, reply);
161 QVariant Core::initSession(UserId uid) {
162 // Find or create session for validated user
164 if(sessions.contains(uid)) sess = sessions[uid];
166 sess = createSession(uid);
169 reply["SessionState"] = sess->sessionState();