LeechCraft  0.6.70-10870-g558588d6ec
Modular cross-platform feature rich live environment.
sysinfo.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #include "sysinfo.h"
31 #if !defined(Q_OS_WIN32)
32 #include <sys/utsname.h>
33 #endif
34 
35 #include <QProcess>
36 #include <QTextStream>
37 #include <QFileInfo>
38 #include <QFile>
39 #include <QSettings>
40 
41 namespace LeechCraft
42 {
43 namespace Util
44 {
45 namespace SysInfo
46 {
47  OSInfo::OSInfo (const QString& arch, const QString& name, const QString& version)
48  : OSInfo { arch, name, name, version }
49  {
50  }
51 
52  OSInfo::OSInfo (const QString& arch, const QString& flavour,
53  const QString& name, const QString& version)
54  : Name_ { name }
55  , Version_ { version }
56  , Flavour_ { flavour }
57  , Arch_ { arch }
58  {
59  }
60 
61  QString GetOSName ()
62  {
63  const auto& info = GetOSInfo ();
64  return info.Name_ + ' ' + info.Version_;
65  }
66 
67  namespace Linux
68  {
69  QString GetLSBName ()
70  {
71  QProcess proc;
72 
73  proc.start (QString ("/bin/sh"),
74  QStringList ("-c") << "lsb_release -ds", QIODevice::ReadOnly);
75  if (proc.waitForStarted ())
76  {
77  QTextStream stream (&proc);
78  QString ret;
79  while (proc.waitForReadyRead ())
80  ret += stream.readAll ();
81  proc.close ();
82  if (!ret.isEmpty ())
83  return ret.remove ('"').trimmed ();
84  }
85 
86  return {};
87  }
88 
89  QString GetEtcOsName ()
90  {
91  if (!QFile::exists ("/etc/os-release"))
92  return {};
93 
94  QSettings relFile { "/etc/os-release", QSettings::IniFormat };
95  relFile.setIniCodec ("UTF-8");
96 
97  const auto& prettyName = relFile.value ("PRETTY_NAME").toString ();
98  const auto& name = relFile.value ("NAME").toString ();
99  const auto& version = relFile.value ("VERSION").toString ();
100  return !prettyName.isEmpty () ? prettyName : (name + " " + version);
101  }
102 
103  QString GetEtcName ()
104  {
105  struct OsInfo_t
106  {
107  QString path;
108  QString name;
109  } OsInfo [] =
110  {
111  { "/etc/mandrake-release", "Mandrake Linux" },
112  { "/etc/debian_version", "Debian GNU/Linux" },
113  { "/etc/gentoo-release", "Gentoo Linux" },
114  { "/etc/exherbo-release", "Exherbo" },
115  { "/etc/arch-release", "Arch Linux" },
116  { "/etc/slackware-version", "Slackware Linux" },
117  { "/etc/pld-release", "" },
118  { "/etc/lfs-release", "LFS" },
119  { "/etc/SuSE-release", "SuSE linux" },
120  { "/etc/conectiva-release", "Connectiva" },
121  { "/etc/.installed", "" },
122  { "/etc/redhat-release", "" },
123  { "", "" }
124  };
125  OsInfo_t *osptr = OsInfo;
126  while (!osptr->path.isEmpty ())
127  {
128  QFile f (osptr->path);
129  if (f.open (QIODevice::ReadOnly))
130  {
131  QString data = QString (f.read (1024)).trimmed ();
132  if (osptr->name.isEmpty ())
133  return data;
134  else
135  return QString ("%1 (%2)")
136  .arg (osptr->name)
137  .arg (data);
138  }
139  ++osptr;
140  }
141 
142  return {};
143  }
144  }
145 
146  namespace
147  {
148 #ifndef Q_OS_MAC
149  void Normalize (QString& osName)
150  {
151  auto trimQuotes = [&osName]
152  {
153  if (osName.startsWith ('"') && osName.endsWith ('"'))
154  osName = osName.mid (1, osName.size () - 1);
155  };
156 
157  trimQuotes ();
158 
159  const QString nameMarker ("NAME=");
160  if (osName.startsWith (nameMarker))
161  osName = osName.mid (nameMarker.size ());
162 
163  trimQuotes ();
164  }
165 #endif
166  }
167 
169  {
170 #if defined(Q_OS_MAC)
171  const auto retVer = [] (const QString& version)
172  {
173  // LC only supports building on OS X 10.7 and higher, which all work only on x86_64.
174  return OSInfo { "x86_64", "Mac OS X", version };
175  };
176 
177  switch (QSysInfo::MacintoshVersion)
178  {
179  case QSysInfo::MV_10_3:
180  return retVer ("10.3");
181  case QSysInfo::MV_10_4:
182  return retVer ("10.4");
183  case QSysInfo::MV_10_5:
184  return retVer ("10.5");
185  case QSysInfo::MV_10_6:
186  return retVer ("10.6");
187  case QSysInfo::MV_10_7:
188  return retVer ("10.7");
189  case QSysInfo::MV_10_8:
190  return retVer ("10.8");
191  case QSysInfo::MV_10_9:
192  return retVer ("10.9");
193  case 0x000C:
194  return retVer ("10.10");
195  default:
196  return retVer ("Unknown version");
197  }
198 #elif defined(Q_OS_WIN32)
199  const auto retVer = [] (const QString& version)
200  {
201  return OSInfo
202  {
203  QSysInfo::WordSize == 64 ? "x86_64" : "x86",
204  "Windows",
205  version
206  };
207  };
208 
209  switch (QSysInfo::WindowsVersion)
210  {
211  case QSysInfo::WV_95:
212  return retVer ("95");
213  case QSysInfo::WV_98:
214  return retVer ("98");
215  case QSysInfo::WV_Me:
216  return retVer ("Me");
217  case QSysInfo::WV_DOS_based:
218  return retVer ("9x/Me");
219  case QSysInfo::WV_NT:
220  return retVer ("NT 4.x");
221  case QSysInfo::WV_2000:
222  return retVer ("2000");
223  case QSysInfo::WV_XP:
224  return retVer ("XP");
225  case QSysInfo::WV_2003:
226  return retVer ("2003");
227  case QSysInfo::WV_VISTA:
228  return retVer ("Vista");
229  case QSysInfo::WV_WINDOWS7:
230  return retVer ("7");
231  case 0x00a0:
232  return retVer ("8");
233  case 0x00b0:
234  return retVer ("8.1");
235  case 0x00c0:
236  return retVer ("10");
237  case QSysInfo::WV_NT_based:
238  return retVer ("NT-based");
239  }
240 #else
241  auto osName = Linux::GetEtcOsName ();
242 
243  if (osName.isEmpty ())
244  osName = Linux::GetEtcName ();
245 
246  if (osName.isEmpty ())
247  osName = Linux::GetLSBName ();
248 
249  Normalize (osName);
250 
251  utsname u;
252  uname (&u);
253 
254  return
255  {
256  u.machine,
257  u.sysname,
258  osName.isEmpty () ? u.sysname : osName,
259  QString ("%1 %2 %3").arg (u.machine, u.release, u.version)
260  };
261 #endif
262 
263  return { "Unknown arch", "Unknown OS", "Unknown version" };
264  }
265 }
266 }
267 }
std::string Name_
QString GetOSName()
Returns a string of OS name and version joined together.
Definition: sysinfo.cpp:61
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:931
Describes the OS running LeechCraft.
Definition: sysinfo.h:49
OSInfo GetOSInfo()
Returns more precise information about OS name and version.
Definition: sysinfo.cpp:168
UTIL_SYS_API OSInfo(const QString &arch, const QString &name, const QString &version)
Constructs the OSInfo object.
Definition: sysinfo.cpp:47