Warning, file /plasma/drkonqi/src/systeminformation.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /******************************************************************* 0002 * systeminformation.cpp 0003 * SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez <andresbajotierra@gmail.com> 0004 * SPDX-FileCopyrightText: 2009 George Kiagiadakis <gkiagia@users.sourceforge.net> 0005 * SPDX-FileCopyrightText: 2019-2022 Harald Sitter <sitter@kde.org> 0006 * 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 * 0009 ******************************************************************/ 0010 0011 #include <config-drkonqi.h> 0012 0013 #include "systeminformation.h" 0014 0015 #if HAVE_UNAME 0016 #include <errno.h> 0017 #include <sys/utsname.h> 0018 #endif 0019 0020 #include "drkonqi_debug.h" 0021 #include <KConfig> 0022 #include <KConfigGroup> 0023 #include <KCoreAddons> 0024 #include <KOSRelease> 0025 #include <KProcess> 0026 #include <KSharedConfig> 0027 #include <KWindowSystem> 0028 #include <QStandardPaths> 0029 #include <kcoreaddons_version.h> 0030 0031 static const QString OS_UNSPECIFIED = QStringLiteral("unspecified"); 0032 static const QString PLATFORM_UNSPECIFIED = QStringLiteral("unspecified"); 0033 0034 // This function maps the operating system to an OS value that is 0035 // accepted by bugs.kde.org. If the values change on the server 0036 // side, they need to be updated here as well. 0037 static QString fetchBasicOperatingSystem() 0038 { 0039 // krazy:excludeall=cpp 0040 // Get the base OS string (bugzillaOS) 0041 #if defined(Q_OS_LINUX) 0042 return QStringLiteral("Linux"); 0043 #elif defined(Q_OS_FREEBSD) 0044 return QStringLiteral("FreeBSD"); 0045 #elif defined(Q_OS_NETBSD) 0046 return QStringLiteral("NetBSD"); 0047 #elif defined(Q_OS_OPENBSD) 0048 return QStringLiteral("OpenBSD"); 0049 #elif defined(Q_OS_AIX) 0050 return QStringLiteral("AIX"); 0051 #elif defined(Q_OS_HPUX) 0052 return QStringLiteral("HP-UX"); 0053 #elif defined(Q_OS_IRIX) 0054 return QStringLiteral("IRIX"); 0055 #elif defined(Q_OS_OSF) 0056 return QStringLiteral("Tru64"); 0057 #elif defined(Q_OS_SOLARIS) 0058 return QStringLiteral("Solaris"); 0059 #elif defined(Q_OS_CYGWIN) 0060 return QStringLiteral("Cygwin"); 0061 #elif defined(Q_OS_DARWIN) 0062 return QStringLiteral("OS X"); 0063 #elif defined(Q_OS_WIN32) 0064 return QStringLiteral("MS Windows"); 0065 #else 0066 return OS_UNSPECIFIED; 0067 #endif 0068 } 0069 0070 SystemInformation::Config::Config() 0071 : basicOperatingSystem(fetchBasicOperatingSystem()) 0072 , lsbReleasePath(QStandardPaths::findExecutable(QStringLiteral("lsb_release"))) 0073 , osReleasePath(/* Use KOSRelease default */) 0074 { 0075 } 0076 0077 SystemInformation::SystemInformation(Config infoConfig, QObject *parent) 0078 : QObject(parent) 0079 , m_bugzillaOperatingSystem(infoConfig.basicOperatingSystem) 0080 , m_bugzillaPlatform(PLATFORM_UNSPECIFIED) 0081 , m_complete(false) 0082 , m_infoConfig(infoConfig) 0083 { 0084 // NOTE: order matters. These require m_bugzillaOperatingSystem to be set! 0085 m_operatingSystem = fetchOSDetailInformation(); 0086 tryToSetBugzillaPlatform(); 0087 0088 KConfigGroup config(KSharedConfig::openConfig(), "SystemInformation"); 0089 m_compiledSources = config.readEntry("CompiledSources", false); 0090 } 0091 0092 SystemInformation::~SystemInformation() 0093 { 0094 KConfigGroup config(KSharedConfig::openConfig(), "SystemInformation"); 0095 config.writeEntry("CompiledSources", m_compiledSources); 0096 config.sync(); 0097 } 0098 0099 void SystemInformation::tryToSetBugzillaPlatform() 0100 { 0101 QString platform = PLATFORM_UNSPECIFIED; 0102 // first, try to guess bugzilla platfrom from the internal OS information 0103 // this should work for BSDs, solaris and windows. 0104 platform = guessBugzillaPlatform(m_bugzillaOperatingSystem); 0105 0106 // if the internal information is not enough, refer to external information 0107 if (platform == PLATFORM_UNSPECIFIED) { 0108 tryToSetBugzillaPlatformFromExternalInfo(); 0109 } else { 0110 setBugzillaPlatform(platform); 0111 } 0112 } 0113 0114 void SystemInformation::tryToSetBugzillaPlatformFromExternalInfo() 0115 { 0116 // Run lsb_release async 0117 QString lsb_release = m_infoConfig.lsbReleasePath; 0118 if (!lsb_release.isEmpty()) { 0119 qCDebug(DRKONQI_LOG) << "found lsb_release"; 0120 auto *process = new KProcess(); 0121 process->setOutputChannelMode(KProcess::OnlyStdoutChannel); 0122 process->setEnv(QStringLiteral("LC_ALL"), QStringLiteral("C")); 0123 *process << lsb_release << QStringLiteral("-sd"); 0124 connect(process, static_cast<void (KProcess::*)(int, QProcess::ExitStatus)>(&KProcess::finished), this, &SystemInformation::lsbReleaseFinished); 0125 process->start(); 0126 } else { 0127 // when lsb_release is unavailable, turn to /etc/os-release 0128 const QString &osReleaseInfo = fetchOSReleaseInformation(); 0129 const QString &platform = guessBugzillaPlatform(osReleaseInfo); 0130 setBugzillaPlatform(platform); 0131 m_complete = true; 0132 } 0133 } 0134 0135 void SystemInformation::lsbReleaseFinished() 0136 { 0137 auto *process = qobject_cast<KProcess *>(sender()); 0138 Q_ASSERT(process); 0139 m_distributionPrettyName = QString::fromLocal8Bit(process->readAllStandardOutput().trimmed()); 0140 process->deleteLater(); 0141 0142 // Guess distro string 0143 QString platform = guessBugzillaPlatform(m_distributionPrettyName); 0144 0145 // if lsb_release doesn't work well, turn to the /etc/os-release file 0146 if (platform == PLATFORM_UNSPECIFIED) { 0147 const QString &osReleaseInfo = fetchOSReleaseInformation(); 0148 platform = guessBugzillaPlatform(osReleaseInfo); 0149 } 0150 0151 setBugzillaPlatform(platform); 0152 m_complete = true; 0153 } 0154 0155 // this function maps the distribution information to an "Hardware Platform" . 0156 // value that is accepted by bugs.kde.org. If the values change on the server . 0157 // side, they need to be updated here as well . 0158 QString SystemInformation::guessBugzillaPlatform(const QString &distroInfo) const 0159 { 0160 static QHash<QString, QString> platforms{{QStringLiteral("suse"), QStringLiteral("openSUSE RPMs")}, 0161 {QStringLiteral("mint"), QStringLiteral("Mint (Ubuntu Based)")}, 0162 {QStringLiteral("lmde"), QStringLiteral("Mint (Debian Based)")}, 0163 {QStringLiteral("ubuntu"), QStringLiteral("Ubuntu Packages")}, 0164 {QStringLiteral("fedora"), QStringLiteral("Fedora RPMs")}, 0165 {QStringLiteral("redhat"), QStringLiteral("RedHat RPMs")}, 0166 {QStringLiteral("gentoo"), QStringLiteral("Gentoo Packages")}, 0167 {QStringLiteral("mandriva"), QStringLiteral("Mandriva RPMs")}, 0168 {QStringLiteral("mageia"), QStringLiteral("Mageia RPMs")}, 0169 {QStringLiteral("slack"), QStringLiteral("Slackware Packages")}, 0170 {QStringLiteral("pclinuxos"), QStringLiteral("PCLinuxOS")}, 0171 {QStringLiteral("pardus"), QStringLiteral("Pardus Packages")}, 0172 {QStringLiteral("freebsd"), QStringLiteral("FreeBSD Ports")}, 0173 {QStringLiteral("netbsd"), QStringLiteral("NetBSD pkgsrc")}, 0174 {QStringLiteral("openbsd"), QStringLiteral("OpenBSD Packages")}, 0175 {QStringLiteral("solaris"), QStringLiteral("Solaris Packages")}, 0176 {QStringLiteral("chakra"), QStringLiteral("Chakra")}, 0177 {QStringLiteral("ms windows"), QStringLiteral("MS Windows")}, 0178 {QStringLiteral("arch"), QStringLiteral("Archlinux Packages")}, 0179 {QStringLiteral("kde neon"), QStringLiteral("Neon Packages")}}; 0180 for (auto it = platforms.constBegin(); it != platforms.constEnd(); ++it) { 0181 if (distroInfo.contains(it.key(), Qt::CaseInsensitive)) { 0182 return it.value(); 0183 } 0184 } 0185 0186 // Debian has multiple platforms. 0187 if (distroInfo.contains(QLatin1String("debian"), Qt::CaseInsensitive)) { 0188 if (distroInfo.contains(QLatin1String("unstable"), Qt::CaseInsensitive)) { 0189 return QStringLiteral("Debian unstable"); 0190 } else if (distroInfo.contains(QLatin1String("testing"), Qt::CaseInsensitive)) { 0191 return QStringLiteral("Debian testing"); 0192 } else { 0193 return QStringLiteral("Debian stable"); 0194 } 0195 } 0196 0197 return PLATFORM_UNSPECIFIED; 0198 } 0199 0200 QString SystemInformation::fetchOSDetailInformation() const 0201 { 0202 // Get complete OS string (and fallback to base string) 0203 QString operatingSystem = m_bugzillaOperatingSystem; 0204 0205 #if HAVE_UNAME 0206 struct utsname buf; 0207 0208 auto unameFunc = &uname; 0209 if (m_infoConfig.unameFunc) { 0210 unameFunc = (decltype(&uname))m_infoConfig.unameFunc; 0211 } 0212 0213 if ((*unameFunc)(&buf) == -1) { 0214 qCDebug(DRKONQI_LOG) << "call to uname failed" << errno; 0215 } else { 0216 operatingSystem = QString::fromLocal8Bit(buf.sysname) + QLatin1Char(' ') + QString::fromLocal8Bit(buf.release) + QLatin1Char(' ') 0217 + QString::fromLocal8Bit(buf.machine); 0218 } 0219 #endif 0220 0221 return operatingSystem; 0222 } 0223 0224 QString SystemInformation::fetchOSReleaseInformation() 0225 { 0226 KOSRelease os(m_infoConfig.osReleasePath); 0227 return m_distributionPrettyName = os.prettyName(); 0228 } 0229 0230 QString SystemInformation::operatingSystem() const 0231 { 0232 return m_operatingSystem; 0233 } 0234 0235 QString SystemInformation::bugzillaOperatingSystem() const 0236 { 0237 return m_bugzillaOperatingSystem; 0238 } 0239 0240 QString SystemInformation::bugzillaPlatform() const 0241 { 0242 return m_bugzillaPlatform; 0243 } 0244 0245 void SystemInformation::setBugzillaPlatform(const QString &platform) 0246 { 0247 m_bugzillaPlatform = platform; 0248 Q_EMIT bugzillaPlatformChanged(); 0249 } 0250 0251 QString SystemInformation::distributionPrettyName() const 0252 { 0253 return m_distributionPrettyName; 0254 } 0255 0256 bool SystemInformation::compiledSources() const 0257 { 0258 return m_compiledSources; 0259 } 0260 0261 void SystemInformation::setCompiledSources(bool compiled) 0262 { 0263 m_compiledSources = compiled; 0264 Q_EMIT compiledSourcesChanged(); 0265 } 0266 0267 QString SystemInformation::qtVersion() const 0268 { 0269 return QString::fromLatin1(qVersion()); 0270 } 0271 0272 QString SystemInformation::frameworksVersion() const 0273 { 0274 return KCoreAddons::versionString(); 0275 } 0276 0277 bool SystemInformation::complete() const 0278 { 0279 return m_complete; 0280 } 0281 0282 QString SystemInformation::windowSystem() const 0283 { 0284 switch (KWindowSystem::platform()) { 0285 case KWindowSystem::Platform::Unknown: 0286 return QStringLiteral("Unknown"); 0287 case KWindowSystem::Platform::X11: 0288 return QStringLiteral("X11"); 0289 case KWindowSystem::Platform::Wayland: 0290 return QStringLiteral("Wayland"); 0291 } 0292 return QStringLiteral("Unknown"); 0293 }