Warning, file /plasma/plasma-workspace/ksmserver/client.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 ksmserver - the KDE session management server 0003 0004 SPDX-FileCopyrightText: 2000 Matthias Ettrich <ettrich@kde.org> 0005 SPDX-FileCopyrightText: 2005 Lubos Lunak <l.lunak@kde.org> 0006 0007 SPDX-FileContributor: Oswald Buddenhagen <ob6@inf.tu-dresden.de> 0008 0009 some code taken from the dcopserver (part of the KDE libraries), which is 0010 SPDX-FileCopyrightText: 1999 Matthias Ettrich <ettrich@kde.org> 0011 SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org> 0012 0013 SPDX-License-Identifier: MIT 0014 */ 0015 0016 #include <config-workspace.h> 0017 0018 #include "client.h" 0019 0020 #include <stdlib.h> 0021 #include <unistd.h> 0022 #ifdef HAVE_SYS_TIME_H 0023 #include <sys/time.h> 0024 #endif 0025 #include <time.h> 0026 0027 #include <QRandomGenerator> 0028 0029 extern KSMServer *the_server; 0030 0031 KSMClient::KSMClient(SmsConn conn) 0032 : smsConn(conn) 0033 { 0034 id = nullptr; 0035 resetState(); 0036 } 0037 0038 KSMClient::~KSMClient() 0039 { 0040 foreach (SmProp *prop, properties) 0041 SmFreeProperty(prop); 0042 if (id) 0043 free((void *)id); 0044 } 0045 0046 SmProp *KSMClient::property(const char *name) const 0047 { 0048 foreach (SmProp *prop, properties) { 0049 if (!qstrcmp(prop->name, name)) 0050 return prop; 0051 } 0052 return nullptr; 0053 } 0054 0055 void KSMClient::resetState() 0056 { 0057 saveYourselfDone = false; 0058 pendingInteraction = false; 0059 waitForPhase2 = false; 0060 wasPhase2 = false; 0061 } 0062 0063 /* 0064 * This fakes SmsGenerateClientID() in case we can't read our own hostname. 0065 * In this case SmsGenerateClientID() returns NULL, but we really want a 0066 * client ID, so we fake one. 0067 */ 0068 Q_GLOBAL_STATIC(QString, my_addr) 0069 char *safeSmsGenerateClientID(SmsConn /*c*/) 0070 { 0071 // Causes delays with misconfigured network :-/. 0072 // char *ret = SmsGenerateClientID(c); 0073 char *ret = nullptr; 0074 if (!ret) { 0075 if (my_addr->isEmpty()) { 0076 // qCWarning(KSMSERVER, "Can't get own host name. Your system is severely misconfigured\n"); 0077 0078 /* Faking our IP address, the 0 below is "unknown" address format 0079 (1 would be IP, 2 would be DEC-NET format) */ 0080 char hostname[256]; 0081 if (gethostname(hostname, 255) != 0) 0082 *my_addr = QStringLiteral("0%1").arg(QRandomGenerator::global()->generate(), 8, 16); 0083 else { 0084 // create some kind of hash for the hostname 0085 int addr[4] = {0, 0, 0, 0}; 0086 int pos = 0; 0087 for (unsigned int i = 0; i < strlen(hostname); ++i, ++pos) 0088 addr[pos % 4] += hostname[i]; 0089 *my_addr = QStringLiteral("0"); 0090 for (int i = 0; i < 4; ++i) 0091 *my_addr += QString::number(addr[i], 16); 0092 } 0093 } 0094 /* Needs to be malloc(), to look the same as libSM */ 0095 ret = (char *)malloc(1 + my_addr->length() + 13 + 10 + 4 + 1 + /*safeness*/ 10); 0096 static int sequence = 0; 0097 0098 if (ret == nullptr) 0099 return nullptr; 0100 0101 sprintf(ret, "1%s%.13ld%.10d%.4d", my_addr->toLatin1().constData(), (long)time(nullptr), getpid(), sequence); 0102 sequence = (sequence + 1) % 10000; 0103 } 0104 return ret; 0105 } 0106 0107 void KSMClient::registerClient(const char *previousId) 0108 { 0109 id = previousId; 0110 if (!id) 0111 id = safeSmsGenerateClientID(smsConn); 0112 SmsRegisterClientReply(smsConn, (char *)id); 0113 SmsSaveYourself(smsConn, SmSaveLocal, false, SmInteractStyleNone, false); 0114 SmsSaveComplete(smsConn); 0115 the_server->clientRegistered(previousId); 0116 } 0117 0118 QString KSMClient::program() const 0119 { 0120 SmProp *p = property(SmProgram); 0121 if (!p || qstrcmp(p->type, SmARRAY8) || p->num_vals < 1) 0122 return QString(); 0123 return QLatin1String((const char *)p->vals[0].value); 0124 } 0125 0126 QStringList KSMClient::restartCommand() const 0127 { 0128 QStringList result; 0129 SmProp *p = property(SmRestartCommand); 0130 if (!p || qstrcmp(p->type, SmLISTofARRAY8) || p->num_vals < 1) 0131 return result; 0132 for (int i = 0; i < p->num_vals; i++) 0133 result += QLatin1String((const char *)p->vals[i].value); 0134 return result; 0135 } 0136 0137 QStringList KSMClient::discardCommand() const 0138 { 0139 QStringList result; 0140 SmProp *p = property(SmDiscardCommand); 0141 if (!p || qstrcmp(p->type, SmLISTofARRAY8) || p->num_vals < 1) 0142 return result; 0143 for (int i = 0; i < p->num_vals; i++) 0144 result += QLatin1String((const char *)p->vals[i].value); 0145 return result; 0146 } 0147 0148 int KSMClient::restartStyleHint() const 0149 { 0150 SmProp *p = property(SmRestartStyleHint); 0151 if (!p || qstrcmp(p->type, SmCARD8) || p->num_vals < 1) 0152 return SmRestartIfRunning; 0153 return *((unsigned char *)p->vals[0].value); 0154 } 0155 0156 QString KSMClient::userId() const 0157 { 0158 SmProp *p = property(SmUserID); 0159 if (!p || qstrcmp(p->type, SmARRAY8) || p->num_vals < 1) 0160 return QString(); 0161 return QLatin1String((const char *)p->vals[0].value); 0162 }