1// LAF Base Library
2// Copyright (c) 2021 Igara Studio S.A.
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include "base/platform.h"
12
13#if LAF_WINDOWS
14 #include <windows.h>
15#elif LAF_LINUX // Unix-like system
16 #include <sys/utsname.h>
17#endif
18
19namespace base {
20
21Platform get_platform()
22{
23 Platform p;
24
25#if LAF_WINDOWS
26
27 // ----------------------------------------------------------------------
28 // Windows
29
30 OSVERSIONINFOEX osv;
31 osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
32 ::GetVersionEx((OSVERSIONINFO*)&osv);
33
34 p.osVer = Version(osv.dwMajorVersion, osv.dwMinorVersion, 0, 0);
35 switch (osv.wProductType) {
36 case VER_NT_DOMAIN_CONTROLLER:
37 case VER_NT_SERVER:
38 p.windowsType = Platform::WindowsType::Server;
39 break;
40 case VER_NT_WORKSTATION:
41 p.windowsType = Platform::WindowsType::NT;
42 break;
43 }
44
45 p.servicePack = Version(osv.wServicePackMajor, osv.wServicePackMinor, 0, 0);
46 p.isWow64 = is_wow64();
47 p.wineVer = get_wine_version();
48
49#elif LAF_MACOS
50
51 // ----------------------------------------------------------------------
52 // Mac OS X/macOS
53
54 p.osVer = get_osx_version();
55
56#elif LAF_LINUX
57
58 // ----------------------------------------------------------------------
59 // Unix like
60
61 #define HAS_VALUE(n) ((n) != values.end() && !(n)->second.empty())
62
63 // Read information from /etc/os-release
64 auto values = get_linux_release_info("/etc/os-release");
65 auto name = values.find("PRETTY_NAME");
66 if (HAS_VALUE(name)) {
67 p.distroName = name->second;
68 }
69 else {
70 name = values.find("NAME");
71 auto ver = values.find("VERSION");
72 if (HAS_VALUE(name)) {
73 p.distroName = name->second;
74 if (HAS_VALUE(ver))
75 p.distroVer = ver->second;
76 }
77 else {
78 // Read information from /etc/lsb-release
79 values = get_linux_release_info("/etc/lsb-release");
80 name = values.find("DISTRIB_DESCRIPTION");
81 if (HAS_VALUE(name)) {
82 p.distroName = name->second;
83 }
84 else {
85 name = values.find("DISTRIB_ID");
86 ver = values.find("DISTRIB_RELEASE");
87 if (HAS_VALUE(name)) {
88 p.distroName = name->second;
89 if (HAS_VALUE(ver))
90 p.distroVer = ver->second;
91 }
92 else {
93 // Last resource, use uname() function
94 struct utsname utsn;
95 uname(&utsn);
96 if (utsn.sysname) p.distroName = utsn.sysname;
97 if (utsn.release) p.distroVer = utsn.release;
98 }
99 }
100 }
101 }
102
103#endif
104
105 return p;
106}
107
108} // namespace base
109