You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.6 KiB
162 lines
4.6 KiB
/* |
|
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); |
|
}
|
|
|