[impl] Linux support implementation
This commit is contained in:
parent
daa0cf7cd6
commit
8640d90350
@ -43,11 +43,12 @@ set(api
|
|||||||
"api/SystemParams.h"
|
"api/SystemParams.h"
|
||||||
"api/SystemParamsProvider.h"
|
"api/SystemParamsProvider.h"
|
||||||
"api/SystemParamsProvider_win.h"
|
"api/SystemParamsProvider_win.h"
|
||||||
|
"api/SystemParamsProvider_linux.h"
|
||||||
)
|
)
|
||||||
source_group("api" FILES ${api})
|
source_group("api" FILES ${api})
|
||||||
|
|
||||||
set(src
|
set(src
|
||||||
"api/OSUtils.cpp"
|
"api/OSUtils_win.cpp"
|
||||||
"src/CachedDownloader.cpp"
|
"src/CachedDownloader.cpp"
|
||||||
"src/CryptoUtils.cpp"
|
"src/CryptoUtils.cpp"
|
||||||
"src/HashUtils.cpp"
|
"src/HashUtils.cpp"
|
||||||
@ -62,6 +63,7 @@ set(src
|
|||||||
"src/SafeFileUtils.h"
|
"src/SafeFileUtils.h"
|
||||||
"src/SystemParams.cpp"
|
"src/SystemParams.cpp"
|
||||||
"src/SystemParamsProvider_win.cpp"
|
"src/SystemParamsProvider_win.cpp"
|
||||||
|
"src/SystemParamsProvider_linux.cpp"
|
||||||
)
|
)
|
||||||
source_group("src" FILES ${src})
|
source_group("src" FILES ${src})
|
||||||
|
|
||||||
@ -70,6 +72,13 @@ set(ALL_FILES
|
|||||||
${src}
|
${src}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
set_source_files_properties(api/OSUtils_win.cpp PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
set_source_files_properties(src/SystemParamsProvider_win.cpp PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
else(WIN32)
|
||||||
|
set_source_files_properties(src/SystemParamsProvider_linux.cpp PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Target
|
# Target
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|||||||
@ -7,10 +7,13 @@ struct SystemParamTypes
|
|||||||
{
|
{
|
||||||
static const std::string biosSerialNum;
|
static const std::string biosSerialNum;
|
||||||
static const std::string computerUUID;
|
static const std::string computerUUID;
|
||||||
|
static const std::string computerSerial;
|
||||||
static const std::string diskSerialNum;
|
static const std::string diskSerialNum;
|
||||||
static const std::string osId;
|
static const std::string osId;
|
||||||
static const std::string nicMac;
|
static const std::string nicMac;
|
||||||
static const std::string mainboardSerialNum;
|
static const std::string mainboardSerialNum;
|
||||||
|
static const std::string cpuIdModel;
|
||||||
|
static const std::string cpuIdHypervisor;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> SystemParams;
|
typedef std::map<std::string, std::string> SystemParams;
|
||||||
|
|||||||
@ -5,4 +5,9 @@
|
|||||||
#include "SystemParamsProvider_win.h"
|
#include "SystemParamsProvider_win.h"
|
||||||
typedef SystemParamsProvider_win SystemParamsProvider;
|
typedef SystemParamsProvider_win SystemParamsProvider;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "SystemParamsProvider_linux.h"
|
||||||
|
typedef SystemParamsProvider_linux SystemParamsProvider;
|
||||||
|
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|||||||
23
api/SystemParamsProvider_linux.h
Normal file
23
api/SystemParamsProvider_linux.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SystemParams.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
class SystemParamsProvider_linuxImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SystemParamsProvider_linux final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SystemParamsProvider_linux();
|
||||||
|
~SystemParamsProvider_linux();
|
||||||
|
|
||||||
|
public:
|
||||||
|
SystemParams retrieveSystemParams();
|
||||||
|
private:
|
||||||
|
std::unique_ptr<detail::SystemParamsProvider_linuxImpl> m_impl;
|
||||||
|
};
|
||||||
@ -9,8 +9,8 @@ cmake_find_package_multi
|
|||||||
|
|
||||||
[options]
|
[options]
|
||||||
libzip:shared=False
|
libzip:shared=False
|
||||||
|
libzip:crypto=False
|
||||||
libcurl:shared=False
|
libcurl:shared=False
|
||||||
libcurl:with_openssl=False
|
libcurl:with_ssl=openssl
|
||||||
libcurl:with_winssl=True
|
|
||||||
boost:shared=False
|
boost:shared=False
|
||||||
cryptopp:shared=False
|
cryptopp:shared=False
|
||||||
|
|||||||
@ -20,6 +20,8 @@
|
|||||||
#include <boost/iostreams/filter/zlib.hpp>
|
#include <boost/iostreams/filter/zlib.hpp>
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/erase.hpp>
|
||||||
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -72,8 +74,8 @@ typedef std::string ParamHash;
|
|||||||
ParamHash fletcher64(const std::string& input)
|
ParamHash fletcher64(const std::string& input)
|
||||||
{
|
{
|
||||||
std::vector<uint32_t> buf((input.size() + sizeof(uint32_t) - 1) / sizeof(uint32_t), 0);
|
std::vector<uint32_t> buf((input.size() + sizeof(uint32_t) - 1) / sizeof(uint32_t), 0);
|
||||||
std::copy_n(std::begin(input), input.size(), stdext::make_checked_array_iterator((std::string::pointer)buf.data(), buf.size() * sizeof(uint32_t)));
|
std::memcpy((std::string::pointer)buf.data(), input.data(), input.size());
|
||||||
auto resInt = ::fletcher64(buf.data(), buf.size());
|
auto resInt = ::fletcher64(buf.data(), static_cast<int>(buf.size()));
|
||||||
return intToHex(resInt);
|
return intToHex(resInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +86,13 @@ int countUniqueCharacters(std::string_view str)
|
|||||||
{
|
{
|
||||||
chars.insert(ch);
|
chars.insert(ch);
|
||||||
}
|
}
|
||||||
return chars.size();
|
return static_cast<int>(chars.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string filterPunctuation(std::string input)
|
||||||
|
{
|
||||||
|
boost::remove_erase_if(input, boost::is_any_of(". :;-_/"));
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemParams skipEmptyParams(const SystemParams& systemParams)
|
SystemParams skipEmptyParams(const SystemParams& systemParams)
|
||||||
@ -92,7 +100,7 @@ SystemParams skipEmptyParams(const SystemParams& systemParams)
|
|||||||
SystemParams result;
|
SystemParams result;
|
||||||
for (const auto& entry : systemParams)
|
for (const auto& entry : systemParams)
|
||||||
{
|
{
|
||||||
if (!entry.second.empty() && entry.second.length() > 1 && countUniqueCharacters(entry.second) > 1)
|
if (!entry.second.empty() && entry.second.length() > 1 && countUniqueCharacters(filterPunctuation(entry.second)) > 1)
|
||||||
{
|
{
|
||||||
result[entry.first] = entry.second;
|
result[entry.first] = entry.second;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
#include "SafeFileUtils.h"
|
#include "SafeFileUtils.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
#include <winerror.h>
|
#include <winerror.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
@ -12,7 +15,11 @@ void safeRemoveFile(const fs::path& p, const fs::path& tempFolder)
|
|||||||
catch (fs::filesystem_error& e)
|
catch (fs::filesystem_error& e)
|
||||||
{
|
{
|
||||||
if (e.code().category() == boost::system::system_category()
|
if (e.code().category() == boost::system::system_category()
|
||||||
|
#ifdef _WIN32
|
||||||
&& e.code().value() == ERROR_ACCESS_DENIED)
|
&& e.code().value() == ERROR_ACCESS_DENIED)
|
||||||
|
#else
|
||||||
|
&& e.code().value() == EACCES)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
auto cleanupFolder = tempFolder;
|
auto cleanupFolder = tempFolder;
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
const std::string SystemParamTypes::biosSerialNum{ "biosSerialNum" };
|
const std::string SystemParamTypes::biosSerialNum{ "biosSerialNum" };
|
||||||
const std::string SystemParamTypes::computerUUID{ "computerUUID" };
|
const std::string SystemParamTypes::computerUUID{ "computerUUID" };
|
||||||
|
const std::string SystemParamTypes::computerSerial{ "computerSerial" };
|
||||||
const std::string SystemParamTypes::diskSerialNum{ "diskSerialNum" };
|
const std::string SystemParamTypes::diskSerialNum{ "diskSerialNum" };
|
||||||
const std::string SystemParamTypes::osId{ "osId" };
|
const std::string SystemParamTypes::osId{ "osId" };
|
||||||
const std::string SystemParamTypes::nicMac{ "nicMac" };
|
const std::string SystemParamTypes::nicMac{ "nicMac" };
|
||||||
const std::string SystemParamTypes::mainboardSerialNum{ "mainboardSerialNum" };
|
const std::string SystemParamTypes::mainboardSerialNum{ "mainboardSerialNum" };
|
||||||
|
const std::string SystemParamTypes::cpuIdModel{ "cpuIdModel" };
|
||||||
|
const std::string SystemParamTypes::cpuIdHypervisor{ "cpuIdHypervisor" };
|
||||||
|
|||||||
474
src/SystemParamsProvider_linux.cpp
Normal file
474
src/SystemParamsProvider_linux.cpp
Normal file
@ -0,0 +1,474 @@
|
|||||||
|
#include "SystemParamsProvider_linux.h"
|
||||||
|
|
||||||
|
#include <boost/process.hpp>
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <regex>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace bp = boost::process; //we will assume this for all further examples
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template< typename T >
|
||||||
|
std::string intToHex( T i )
|
||||||
|
{
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << std::setfill ('0') << std::setw(sizeof(T)*2)
|
||||||
|
<< std::hex << i;
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> splitString(const std::string& str, char c = ' ')
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
|
||||||
|
auto it = str.cbegin();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
auto firstIt = it;
|
||||||
|
|
||||||
|
while(*it != c && it != str.cend()) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.emplace_back(firstIt, it);
|
||||||
|
} while (it++ != str.cend());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> readFileLine(const std::string& fileName)
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::ifstream myfile(fileName);
|
||||||
|
if (myfile.is_open()) {
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "File " << fileName << " successfully open";
|
||||||
|
if (getline (myfile,line)) {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
myfile.close();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> loadOsId()
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Trying to find Operating system ID...";
|
||||||
|
auto machineId = readFileLine("/var/lib/dbus/machine-id");
|
||||||
|
if (machineId.value_or("").empty()) {
|
||||||
|
machineId = readFileLine("/etc/machine-id");
|
||||||
|
}
|
||||||
|
return machineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> loadBoardSerial()
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Trying to find mainboard serial number...";
|
||||||
|
return readFileLine("/sys/class/dmi/id/board_serial");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> loadComputerUUID()
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Trying to find product UUID...";
|
||||||
|
return readFileLine("/sys/class/dmi/id/product_uuid");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> loadComputerSerial()
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Trying to find computer serial number...";
|
||||||
|
auto productSerial = readFileLine("/sys/class/dmi/id/product_serial");
|
||||||
|
|
||||||
|
if(!productSerial.value_or("").empty()) {
|
||||||
|
auto productFamily = readFileLine("/sys/class/dmi/id/product_family");
|
||||||
|
auto productName = readFileLine("/sys/class/dmi/id/product_name");
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
os << productFamily.value() << "/" << productName.value() << "/" << productSerial.value();
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CpuIdInfo {
|
||||||
|
uint32_t vendorId;
|
||||||
|
std::string vendorString;
|
||||||
|
uint32_t modelId;
|
||||||
|
bool isHypervisor;
|
||||||
|
std::string serialNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
CpuIdInfo loadCpuId()
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Trying to find processor idenfication...";
|
||||||
|
uint32_t a, b, c, d;
|
||||||
|
__cpuid (0 /* vendor string */, a, b, c, d);
|
||||||
|
std::cout << "EAX: " << std::hex << std::setw(8) << std::setfill('0') << a << "\nEBX: " << b << "\nECX: " << c << "\nEDX: " << d << "\n";
|
||||||
|
uint32_t vendorId = a;
|
||||||
|
uint32_t vendorString[] = {b, d, c, 0};
|
||||||
|
|
||||||
|
__cpuid (1 /* Processor Info and Feature Bits */, a, b, c, d);
|
||||||
|
std::cout << "EAX: " << std::hex << std::setw(8) << std::setfill('0') << a << "\nEBX: " << b << "\nECX: " << c << "\nEDX: " << d << "\n";
|
||||||
|
bool isHypervisor = c & 0x80000000;
|
||||||
|
uint32_t modelId = a & 0b00001111111111110011111111111111;
|
||||||
|
|
||||||
|
__cpuid (3 /* Processor Serial Number */, a, b, c, d);
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::hex << std::setw(8) << std::setfill('0') << a << "-"
|
||||||
|
<< std::hex << std::setw(8) << std::setfill('0') << b << "-"
|
||||||
|
<< std::hex << std::setw(8) << std::setfill('0') << c << "-"
|
||||||
|
<< std::hex << std::setw(8) << std::setfill('0') << d;
|
||||||
|
|
||||||
|
return CpuIdInfo {vendorId, std::string((const char*)vendorString), modelId, isHypervisor, oss.str()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::pair<std::string, std::string>> matchParameter(
|
||||||
|
const std::string& line,
|
||||||
|
const std::string& parameterRegex,
|
||||||
|
const std::string& valueRegex = "([0-9a-fA-F\\-_]+)$"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::regex line_regex(parameterRegex + ": " + valueRegex);
|
||||||
|
std::smatch line_match;
|
||||||
|
if(std::regex_search(line, line_match, line_regex)) {
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Matched parameter pair " << line_match[1] << ": " << line_match[2];
|
||||||
|
return std::make_pair<std::string, std::string>(line_match[1], line_match[2]);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DmiDecodeParamTypes
|
||||||
|
{
|
||||||
|
static const std::string biosSerialNum;
|
||||||
|
static const std::string systemUUID;
|
||||||
|
static const std::string systemSerialNum;
|
||||||
|
static const std::string systemFamily;
|
||||||
|
static const std::string systemProductNumber;
|
||||||
|
static const std::string baseboardSerialNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::string DmiDecodeParamTypes::systemUUID = "systemUUID";
|
||||||
|
const std::string DmiDecodeParamTypes::systemSerialNum = "systemSerialNum";
|
||||||
|
const std::string DmiDecodeParamTypes::systemFamily = "systemFamily";
|
||||||
|
const std::string DmiDecodeParamTypes::systemProductNumber = "systemProductNumber";
|
||||||
|
const std::string DmiDecodeParamTypes::baseboardSerialNumber = "baseboardSerialNumber";
|
||||||
|
|
||||||
|
std::map<std::string, std::string> read_dmidecode()
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
std::map<std::string, std::string> output;
|
||||||
|
bp::ipstream is; //reading pipe-stream
|
||||||
|
bp::child c("/usr/sbin/dmidecode", ec, bp::std_out > is, bp::std_err > bp::null);
|
||||||
|
|
||||||
|
if(ec) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::regex section_regex("DMI type ([0-9]+)");
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
int section = -1;
|
||||||
|
while (std::getline(is, line)) {
|
||||||
|
if (!line.empty() && line[0] != '\t') {
|
||||||
|
std::smatch section_match;
|
||||||
|
if(std::regex_search(line, section_match, section_regex)) {
|
||||||
|
section = std::atoi(section_match[1].str().c_str());
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Found section: " << section_match[1];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section == 1) {
|
||||||
|
{
|
||||||
|
const auto matchedParameter = matchParameter(line, "(UUID)");
|
||||||
|
if (matchedParameter.has_value()) {
|
||||||
|
output["systemUUID"] = matchedParameter.value().second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto matchedParameter = matchParameter(line, "(Serial Number)", "([0-9a-zA-Z\\-_]+)$");
|
||||||
|
if (matchedParameter.has_value()) {
|
||||||
|
output["systemSerialNumber"] = matchedParameter.value().second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto matchedParameter = matchParameter(line, "(Family)", "([0-9a-zA-Z\\-_ ]+)$");
|
||||||
|
if (matchedParameter.has_value()) {
|
||||||
|
output["systemFamily"] = matchedParameter.value().second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto matchedParameter = matchParameter(line, "(Product name)", "([0-9a-zA-Z\\-_ ]+)$");
|
||||||
|
if (matchedParameter.has_value()) {
|
||||||
|
output["systemProductName"] = matchedParameter.value().second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (section == 2) {
|
||||||
|
{
|
||||||
|
const auto matchedParameter = matchParameter(line, "(Serial Number)", "([0-9a-zA-Z\\-_]+)$");
|
||||||
|
if (matchedParameter.has_value()) {
|
||||||
|
output["baseboardSerialNumber"] = matchedParameter.value().second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
c.wait(ec);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> readMacAddresses()
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
std::map<std::string, std::string> output;
|
||||||
|
bp::ipstream is; //reading pipe-stream
|
||||||
|
bp::child c("/usr/bin/find /sys/class/net -mindepth 1 -maxdepth 1 ! -name lo -printf \"%P: \" -execdir /usr/bin/cat {}/address ;", ec, bp::std_out > is, bp::std_err > bp::null);
|
||||||
|
if (ec) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::regex section_regex("([0-9a-zA-Z\\-_]+): ([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})");
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
int section = -1;
|
||||||
|
while (std::getline(is, line)) {
|
||||||
|
if (!line.empty() && line[0] == 'e') {
|
||||||
|
std::smatch section_match;
|
||||||
|
if(std::regex_match(line, section_match, section_regex)) {
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Found device : " << section_match[1] << " with MAC : " << section_match[2];
|
||||||
|
output[section_match[1]] = section_match[2];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.wait(ec);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LsBlkResultEntry{
|
||||||
|
std::string mountPoint;
|
||||||
|
std::string parentName;
|
||||||
|
std::string name;
|
||||||
|
std::string model;
|
||||||
|
std::string serial;
|
||||||
|
std::string type;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<LsBlkResultEntry> parseLsBlkResultEntry(const std::string& line)
|
||||||
|
{
|
||||||
|
auto cols = splitString(line, ' ');
|
||||||
|
if(cols.size() == 6) {
|
||||||
|
return LsBlkResultEntry{
|
||||||
|
cols[0],cols[1],cols[2],cols[3],cols[4],cols[5]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> readDiskSerial()
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
bp::ipstream is; //reading pipe-stream
|
||||||
|
bp::child c("/usr/bin/lsblk -oMOUNTPOINT,PKNAME,NAME,MODEL,SERIAL,TYPE --raw", ec, bp::std_out > is, bp::std_err > bp::null);
|
||||||
|
|
||||||
|
if (ec) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<LsBlkResultEntry> cmdOut;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
int section = -1;
|
||||||
|
while (std::getline(is, line)) {
|
||||||
|
if (!line.empty()) {
|
||||||
|
const auto entry = parseLsBlkResultEntry(line);
|
||||||
|
if (entry.has_value()) {
|
||||||
|
cmdOut.push_back(entry.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.wait(ec);
|
||||||
|
if(ec) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find best mountpoint
|
||||||
|
LsBlkResultEntry const* bestEntry = nullptr;
|
||||||
|
for (const auto& entry: cmdOut) {
|
||||||
|
if(entry.mountPoint == "/") {
|
||||||
|
bestEntry = &entry;
|
||||||
|
}
|
||||||
|
else if(entry.mountPoint == "/boot" && (bestEntry == nullptr || bestEntry->mountPoint == "/sysroot")) {
|
||||||
|
bestEntry = &entry;
|
||||||
|
}
|
||||||
|
else if(entry.mountPoint == "/sysroot" && bestEntry == nullptr) {
|
||||||
|
bestEntry = &entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bestEntry == nullptr)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "Found best mount point: " << bestEntry->mountPoint;
|
||||||
|
|
||||||
|
int depth = 0;
|
||||||
|
while(depth < 10 && !bestEntry->parentName.empty()) {
|
||||||
|
++depth;
|
||||||
|
bool found = false;
|
||||||
|
for (const auto& entry: cmdOut) {
|
||||||
|
if (entry.name == bestEntry->parentName) {
|
||||||
|
bestEntry = &entry;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestEntry->type == "disk" && !bestEntry->serial.empty()) {
|
||||||
|
return bestEntry->serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
class SystemParamsProvider_linuxImpl final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SystemParamsProvider_linuxImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~SystemParamsProvider_linuxImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
SystemParams retrieveSystemParams()
|
||||||
|
{
|
||||||
|
SystemParams result;
|
||||||
|
// result[SystemParamTypes::biosSerialNum] = processiosData(biosFuture.get());
|
||||||
|
{
|
||||||
|
const auto val = loadComputerUUID();
|
||||||
|
if (val.has_value()) {
|
||||||
|
result[SystemParamTypes::computerUUID] = val.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto val = loadComputerSerial();
|
||||||
|
if (val.has_value()) {
|
||||||
|
result[SystemParamTypes::computerSerial] = val.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto val = loadOsId();
|
||||||
|
if (val.has_value()) {
|
||||||
|
result[SystemParamTypes::osId] = val.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto val = loadBoardSerial();
|
||||||
|
if (val.has_value()) {
|
||||||
|
result[SystemParamTypes::mainboardSerialNum] = val.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cpuIdInfo = loadCpuId();
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Vendor ID: " << cpuIdInfo.vendorId << std::endl;
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Model ID: " << cpuIdInfo.modelId << std::endl;
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Vendor String: " << cpuIdInfo.vendorString << std::endl;
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Is hypervisor: " << cpuIdInfo.isHypervisor << std::endl;
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Serial number: " << cpuIdInfo.serialNumber << std::endl;
|
||||||
|
|
||||||
|
result[SystemParamTypes::cpuIdModel] = intToHex(cpuIdInfo.vendorId) + intToHex(cpuIdInfo.modelId);
|
||||||
|
if(cpuIdInfo.isHypervisor) {
|
||||||
|
result[SystemParamTypes::cpuIdHypervisor] = "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto macAddresses = readMacAddresses();
|
||||||
|
if(macAddresses.size() > 0)
|
||||||
|
{
|
||||||
|
result[SystemParamTypes::nicMac] = macAddresses.begin()->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto diskSerial = readDiskSerial();
|
||||||
|
if (diskSerial.has_value()) {
|
||||||
|
result[SystemParamTypes::diskSerialNum] = diskSerial.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result2 = read_dmidecode();
|
||||||
|
for (auto it = result2.cbegin(); it != result2.cend(); ++it) {
|
||||||
|
std::cout << it->first << ": " << it->second << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.find(SystemParamTypes::mainboardSerialNum) == result.end() &&
|
||||||
|
result2.find(DmiDecodeParamTypes::baseboardSerialNumber) != result2.end()) {
|
||||||
|
result[SystemParamTypes::mainboardSerialNum] = result2[DmiDecodeParamTypes::baseboardSerialNumber];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.find(SystemParamTypes::computerUUID) == result.end() &&
|
||||||
|
result2.find(DmiDecodeParamTypes::systemUUID) != result2.end()) {
|
||||||
|
result[SystemParamTypes::computerUUID] = result2[DmiDecodeParamTypes::systemUUID];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.find(SystemParamTypes::computerSerial) == result.end() &&
|
||||||
|
result2.find(DmiDecodeParamTypes::systemSerialNum) != result2.end()) {
|
||||||
|
if(!result2[DmiDecodeParamTypes::systemUUID].empty()) {
|
||||||
|
auto productFamily = result2.find(DmiDecodeParamTypes::systemFamily);
|
||||||
|
auto productName = result2.find(DmiDecodeParamTypes::systemProductNumber);
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
os << ((productFamily != result2.end()) ? productFamily->second : "")
|
||||||
|
<< "/" << ((productName != result2.end()) ? productName->second : "")
|
||||||
|
<< "/" << result2[DmiDecodeParamTypes::systemUUID];
|
||||||
|
result[SystemParamTypes::computerSerial] = os.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemParamsProvider_linux::SystemParamsProvider_linux()
|
||||||
|
: m_impl(std::make_unique<detail::SystemParamsProvider_linuxImpl>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemParamsProvider_linux::~SystemParamsProvider_linux()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemParams SystemParamsProvider_linux::retrieveSystemParams()
|
||||||
|
{
|
||||||
|
return m_impl->retrieveSystemParams();
|
||||||
|
}
|
||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user