Brooklyn/plasma/workspace/ksmserver/client.cpp

163 lines
4.6 KiB
C++
Raw Normal View History

2022-03-05 17:41:29 +00:00
/*
ksmserver - the KDE session management server
SPDX-FileCopyrightText: 2000 Matthias Ettrich <ettrich@kde.org>
SPDX-FileCopyrightText: 2005 Lubos Lunak <l.lunak@kde.org>
SPDX-FileContributor: Oswald Buddenhagen <ob6@inf.tu-dresden.de>
some code taken from the dcopserver (part of the KDE libraries), which is
SPDX-FileCopyrightText: 1999 Matthias Ettrich <ettrich@kde.org>
SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org>
SPDX-License-Identifier: MIT
*/
#include <config-workspace.h>
#include "client.h"
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <time.h>
#include <QRandomGenerator>
extern KSMServer *the_server;
KSMClient::KSMClient(SmsConn conn)
{
smsConn = conn;
id = nullptr;
resetState();
}
KSMClient::~KSMClient()
{
foreach (SmProp *prop, properties)
SmFreeProperty(prop);
if (id)
free((void *)id);
}
SmProp *KSMClient::property(const char *name) const
{
foreach (SmProp *prop, properties) {
if (!qstrcmp(prop->name, name))
return prop;
}
return nullptr;
}
void KSMClient::resetState()
{
saveYourselfDone = false;
pendingInteraction = false;
waitForPhase2 = false;
wasPhase2 = false;
}
/*
* This fakes SmsGenerateClientID() in case we can't read our own hostname.
* In this case SmsGenerateClientID() returns NULL, but we really want a
* client ID, so we fake one.
*/
Q_GLOBAL_STATIC(QString, my_addr)
char *safeSmsGenerateClientID(SmsConn /*c*/)
{
// Causes delays with misconfigured network :-/.
// char *ret = SmsGenerateClientID(c);
char *ret = nullptr;
if (!ret) {
if (my_addr->isEmpty()) {
// qCWarning(KSMSERVER, "Can't get own host name. Your system is severely misconfigured\n");
/* Faking our IP address, the 0 below is "unknown" address format
(1 would be IP, 2 would be DEC-NET format) */
char hostname[256];
if (gethostname(hostname, 255) != 0)
*my_addr = QStringLiteral("0%1").arg(QRandomGenerator::global()->generate(), 8, 16);
else {
// create some kind of hash for the hostname
int addr[4] = {0, 0, 0, 0};
int pos = 0;
for (unsigned int i = 0; i < strlen(hostname); ++i, ++pos)
addr[pos % 4] += hostname[i];
*my_addr = QStringLiteral("0");
for (int i = 0; i < 4; ++i)
*my_addr += QString::number(addr[i], 16);
}
}
/* Needs to be malloc(), to look the same as libSM */
ret = (char *)malloc(1 + my_addr->length() + 13 + 10 + 4 + 1 + /*safeness*/ 10);
static int sequence = 0;
if (ret == nullptr)
return nullptr;
sprintf(ret, "1%s%.13ld%.10d%.4d", my_addr->toLatin1().constData(), (long)time(nullptr), getpid(), sequence);
sequence = (sequence + 1) % 10000;
}
return ret;
}
void KSMClient::registerClient(const char *previousId)
{
id = previousId;
if (!id)
id = safeSmsGenerateClientID(smsConn);
SmsRegisterClientReply(smsConn, (char *)id);
SmsSaveYourself(smsConn, SmSaveLocal, false, SmInteractStyleNone, false);
SmsSaveComplete(smsConn);
the_server->clientRegistered(previousId);
}
QString KSMClient::program() const
{
SmProp *p = property(SmProgram);
if (!p || qstrcmp(p->type, SmARRAY8) || p->num_vals < 1)
return QString();
return QLatin1String((const char *)p->vals[0].value);
}
QStringList KSMClient::restartCommand() const
{
QStringList result;
SmProp *p = property(SmRestartCommand);
if (!p || qstrcmp(p->type, SmLISTofARRAY8) || p->num_vals < 1)
return result;
for (int i = 0; i < p->num_vals; i++)
result += QLatin1String((const char *)p->vals[i].value);
return result;
}
QStringList KSMClient::discardCommand() const
{
QStringList result;
SmProp *p = property(SmDiscardCommand);
if (!p || qstrcmp(p->type, SmLISTofARRAY8) || p->num_vals < 1)
return result;
for (int i = 0; i < p->num_vals; i++)
result += QLatin1String((const char *)p->vals[i].value);
return result;
}
int KSMClient::restartStyleHint() const
{
SmProp *p = property(SmRestartStyleHint);
if (!p || qstrcmp(p->type, SmCARD8) || p->num_vals < 1)
return SmRestartIfRunning;
return *((unsigned char *)p->vals[0].value);
}
QString KSMClient::userId() const
{
SmProp *p = property(SmUserID);
if (!p || qstrcmp(p->type, SmARRAY8) || p->num_vals < 1)
return QString();
return QLatin1String((const char *)p->vals[0].value);
}