/*************************************************************************** * Copyright (c) 2015 Pier Luigi Fiorini * Copyright (c) 2013 Abdurrahman AVCI * * 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) any later version. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ***************************************************************************/ #include "SocketServer.h" #include "DaemonApp.h" #include "Messages.h" #include "PowerManager.h" #include "SocketWriter.h" #include "Utils.h" #include namespace SDDM { SocketServer::SocketServer(QObject *parent) : QObject(parent) { } QString SocketServer::socketAddress() const { if (m_server) return m_server->fullServerName(); return QString(); } bool SocketServer::start(const QString &displayName) { // check if the server has been created already if (m_server) return false; QString socketName = QStringLiteral("sddm-%1-%2").arg(displayName).arg(generateName(6)); // log message qDebug() << "Socket server starting..."; // create server m_server = new QLocalServer(this); // set server options m_server->setSocketOptions(QLocalServer::UserAccessOption); // start listening if (!m_server->listen(socketName)) { // log message qCritical() << "Failed to start socket server."; // return fail return false; } // log message qDebug() << "Socket server started."; // connect signals connect(m_server, &QLocalServer::newConnection, this, &SocketServer::newConnection); // return success return true; } void SocketServer::stop() { // check flag if (!m_server) return; // log message qDebug() << "Socket server stopping..."; // delete server m_server->deleteLater(); m_server = nullptr; // log message qDebug() << "Socket server stopped."; } void SocketServer::newConnection() { // get pending connection QLocalSocket *socket = m_server->nextPendingConnection(); // connect signals connect(socket, &QLocalSocket::readyRead, this, &SocketServer::readyRead); connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater); } void SocketServer::readyRead() { QLocalSocket *socket = qobject_cast(sender()); // check socket if (!socket) return; // input stream QDataStream input(socket); // Qt's QLocalSocket::readyRead is not designed to be called at every socket.write(), // so we need to use a loop to read all the signals. while(socket->bytesAvailable()) { // read message quint32 message; input >> message; switch (GreeterMessages(message)) { case GreeterMessages::Connect: { // log message qDebug() << "Message received from greeter: Connect"; // send capabilities SocketWriter(socket) << quint32(DaemonMessages::Capabilities) << quint32(daemonApp->powerManager()->capabilities()); // send host name SocketWriter(socket) << quint32(DaemonMessages::HostName) << daemonApp->hostName(); // emit signal emit connected(); } break; case GreeterMessages::Login: { // log message qDebug() << "Message received from greeter: Login"; // read username, pasword etc. QString user, password, filename; Session session; input >> user >> password >> session; // emit signal emit login(socket, user, password, session); } break; case GreeterMessages::PowerOff: { // log message qDebug() << "Message received from greeter: PowerOff"; // power off daemonApp->powerManager()->powerOff(); } break; case GreeterMessages::Reboot: { // log message qDebug() << "Message received from greeter: Reboot"; // reboot daemonApp->powerManager()->reboot(); } break; case GreeterMessages::Suspend: { // log message qDebug() << "Message received from greeter: Suspend"; // suspend daemonApp->powerManager()->suspend(); } break; case GreeterMessages::Hibernate: { // log message qDebug() << "Message received from greeter: Hibernate"; // hibernate daemonApp->powerManager()->hibernate(); } break; case GreeterMessages::HybridSleep: { // log message qDebug() << "Message received from greeter: HybridSleep"; // hybrid sleep daemonApp->powerManager()->hybridSleep(); } break; default: { // log message qWarning() << "Unknown message" << message; } } } } void SocketServer::loginFailed(QLocalSocket *socket) { SocketWriter(socket) << quint32(DaemonMessages::LoginFailed); } void SocketServer::loginSucceeded(QLocalSocket *socket) { SocketWriter(socket) << quint32(DaemonMessages::LoginSucceeded); } void SocketServer::informationMessage(QLocalSocket *socket, const QString &message) { SocketWriter(socket) << quint32(DaemonMessages::InformationMessage) << message; } }