pmt: Write the function base

- Write the function manager.
 - Make minor changes to the function structure.
 - Add CLI11 license.
 - Added main function to libpmt.
This commit is contained in:
2025-07-28 22:36:15 +03:00
parent 40260d5ae3
commit a58adb6a28
13 changed files with 280 additions and 80 deletions

25
include/CLI/LICENSE Normal file
View File

@@ -0,0 +1,25 @@
CLI11 2.5 Copyright (c) 2017-2025 University of Cincinnati, developed by Henry
Schreiner under NSF AWARD 1414736. All rights reserved.
Redistribution and use in source and binary forms of CLI11, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -14,6 +14,13 @@
limitations under the License. limitations under the License.
*/ */
/**
* WARNING
* --------
* This library (libpmt) isn't exactly suitable for use in different projects.
* But I'm not saying I've tested it or anything like that.
*/
#ifndef LIBPMT_LIB_HPP #ifndef LIBPMT_LIB_HPP
#define LIBPMT_LIB_HPP #define LIBPMT_LIB_HPP
@@ -25,9 +32,12 @@
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <libpartition_map/lib.hpp> #include <libpartition_map/lib.hpp>
#define PMT "libpmt"
#define PMTE "pmt"
#define PMTF "libpmt-function-manager"
#ifdef NEED_BASIC_FUNCTION_CLASSES #ifdef NEED_BASIC_FUNCTION_CLASSES
#include <memory> #include <memory>
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignore "-Wdeprecated-declarations" #pragma GCC diagnostic ignore "-Wdeprecated-declarations"
#include <CLI/CLI11.hpp> #include <CLI/CLI11.hpp>
@@ -36,12 +46,11 @@
namespace PartitionManager { namespace PartitionManager {
#ifdef NEED_BASIC_FUNCTION_CLASSES
class basic_function { class basic_function {
/** /**
* Example variables for writing your function: * Example variables for writing your function:
* private: * public:
* CLI::App _cmd* = nullptr; * CLI::App cmd* = nullptr;
*/ */
public: public:
virtual bool init(CLI::App& _app) = 0; virtual bool init(CLI::App& _app) = 0;
@@ -56,25 +65,35 @@ private:
public: public:
void registerFunction(std::unique_ptr<basic_function> _func, CLI::App& _app); void registerFunction(std::unique_ptr<basic_function> _func, CLI::App& _app);
const char* whatIsRunnedCommandName();
void startUsedFunctions(); bool handleAll();
};
class basic_variables {
public:
basic_variables();
PartitionMap::BuildMap PartMap;
std::string searchPath;
bool onLogical;
bool silentProcess;
bool verboseMode;
bool viewVersion;
}; };
using FunctionBase = basic_function; using FunctionBase = basic_function;
using FunctionManager = basic_function_manager; using FunctionManager = basic_function_manager;
using VariableTable = basic_variables;
using Error = Helper::Error;
#endif // #ifdef NEED_BASIC_FUNCTION_CLASSES VariableTable* Variables;
namespace Variables {
extern PartitionMap::BuildMap PartMap;
} // namespace Variables
int Main(int argc, char** argv); int Main(int argc, char** argv);
std::string getLibVersion(); std::string getLibVersion();
std::string getAppVersion(); std::string getAppVersion(); // Not Android app version (an Android app is planned!), tells pmt and libs versions.
} // namespace PartitionManager } // namespace PartitionManager

View File

@@ -0,0 +1,54 @@
/*
Copyright 2025 Yağız Zengin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <vector>
#include <memory>
#include <string>
#include <libpmt/lib.hpp>
namespace PartitionManager {
void basic_function_manager::registerFunction(std::unique_ptr<basic_function> _func, CLI::App& _app)
{
LOGN(PMTF, INFO) << "registering function: " << _func->name() << std::endl;
if (!_func->init(_app)) throw Error("Cannot init function: %s\n", _func->name());
_functions.push_back(std::move(_func));
LOGN(PMTF, INFO) << _func->name() << " successfully registered." << std::endl;
}
const char* basic_function_manager::whatIsRunnedCommandName()
{
for (auto &func : _functions) {
if (func->cmd->parsed()) return func->name();
}
return nullptr;
}
bool basic_function_manager::handleAll()
{
LOGN(PMTF, INFO) << "running catched function commands in command-line." << std::endl;
for (auto &func : _functions) {
if (func->cmd->parsed()) {
LOGN(PMTF, INFO) << "running function: " << func->name() << std::endl;
return (func->run()) ? true : false;
}
}
return false;
}
} // namespace PartitionManager

View File

@@ -0,0 +1,81 @@
/*
Copyright 2025 Yağız Zengin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <libpmt/lib.hpp>
namespace PartitionManager {
VariableTable::VariableTable() : PartMap(),
searchPath(""),
onLogical(false),
silentProcess(false),
verboseMode(false),
viewVersion(false)
{}
VariableTable* Variables = new VariableTable();
int Main(int argc, char** argv)
{
try { // try-catch start
CLI::App AppMain{"Partition Manager Tool"};
FunctionManager FuncManager;
AppMain.add_option("-S,--search-path", Variables->searchPath, "Set partition search path");
AppMain.add_flag("-l,--logical", Variables->onLogical, "Specify that the target partition is dynamic");
AppMain.add_flag("-s,--silent", Variables->silentProcess, "The process is performed silently without any output.");
AppMain.add_flag("-V,--verbose", Variables->verboseMode, "Detailed information is written on the screen while the transaction is being carried out");
AppMain.add_flag("-v,--version", Variables->viewVersion, "Print version and exit");
FuncManager.registerFunction(std::make_unique<backupFunction>, AppMain);
FuncManager.registerFunction(std::make_unique<flashFunction>, AppMain);
FuncManager.registerFunction(std::make_unique<eraseFunction>, AppMain);
FuncManager.registerFunction(std::make_unique<partitionSizeFunction>, AppMain);
CLI11_PARSE(AppMain, argc, argv);
const char* used = FuncManager.whatIsRunnedCommandName();
if (used != nullptr)
LOGN(PMTE, INFO) << "used command: " << used << std::endl;
if (!Variables->searchPath.empty())
Variables->PartMap(searchPath);
if (!Variables->PartMap) {
if (Variables->searchPath.empty())
throw Error("No default search entries were found. Specify a search directory with -S (--search-path)");
}
FuncManager.handleAll();
} catch (Helper::Error &error) { // catch Helper::Error
if (!Variables->silentProcess) fprintf(stde9rr, "%s: %s.\n", argv[0], error.what());
delete Variables;
return -1;
} catch (CLI::ParseError &error) { // catch CLI::ParseError
fprintf(stderr, "%s: FLAG PARSE ERROR: %s\n", argv[0], error.what());
return -1;
} // try-catch block end
}
} // namespace PartitionManager

View File

@@ -0,0 +1,23 @@
/*
Copyright 2025 Yağız Zengin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <libpmt/lib.hpp>
int main(int argc, char** argv)
{
// Call integrated main function in library
return PartitionManager::Main(argc, argv);
}

View File

@@ -21,10 +21,9 @@ namespace PartitionManager {
// Back-up function // Back-up function
class backupFunction : public PartitionManager::FunctionBase { class backupFunction : public PartitionManager::FunctionBase {
private:
CLI::App* _cmd = nullptr;
public: public:
CLI::App* cmd = nullptr;
bool init(CLI::App& _app) override; bool init(CLI::App& _app) override;
bool run() override; bool run() override;
const char* name() override; const char* name() override;
@@ -32,10 +31,9 @@ public:
// Image flasher function // Image flasher function
class flashFunction : public PartitionManager::FunctionBase { class flashFunction : public PartitionManager::FunctionBase {
private:
CLI::App* _cmd = nullptr;
public: public:
CLI::App* cmd = nullptr;
bool init(CLI::App& _app) override; bool init(CLI::App& _app) override;
bool run() override; bool run() override;
const char* name() override; const char* name() override;
@@ -43,10 +41,9 @@ public:
// Eraser function (only the partition content is cleared) // Eraser function (only the partition content is cleared)
class eraseFunction : public PartitionManager::FunctionBase { class eraseFunction : public PartitionManager::FunctionBase {
private:
CLI::App* _cmd = nullptr;
public: public:
CLI::App* cmd = nullptr;
bool init(CLI::App& _app) override; bool init(CLI::App& _app) override;
bool run() override; bool run() override;
const char* name() override; const char* name() override;
@@ -54,10 +51,9 @@ public:
// Partition size getter function // Partition size getter function
class partitionSizeFunction : public PartitionManager::FunctionBase { class partitionSizeFunction : public PartitionManager::FunctionBase {
private:
CLI::App* _cmd = nullptr;
public: public:
CLI::App* cmd = nullptr;
bool init(CLI::App& _app) override; bool init(CLI::App& _app) override;
bool run() override; bool run() override;
const char* name() override; const char* name() override;

View File

@@ -45,11 +45,11 @@ class Logger {
private: private:
LogLevels _level; LogLevels _level;
std::ostringstream _oss; std::ostringstream _oss;
const char *_logFile, *_program_name, *_file; const char *_funcname, *_logFile, *_program_name, *_file;
int _line; int _line;
public: public:
Logger(LogLevels level, const char* file, const char* name, const char* sfile, int line); Logger(LogLevels level, const char* func, const char* file, const char* name, const char* sfile, int line);
~Logger(); ~Logger();
template <typename T> template <typename T>
@@ -185,15 +185,15 @@ std::string getLibVersion();
fprintf(stdout, "%s%sINFO%s: %s", BOLD, GREEN, STYLE_RESET, msg); fprintf(stdout, "%s%sINFO%s: %s", BOLD, GREEN, STYLE_RESET, msg);
#endif // #ifndef NO_C_TYPE_HANDLERS #endif // #ifndef NO_C_TYPE_HANDLERS
#define LOG(level) Helper::Logger(level, Helper::LoggingProperties::FILE.data(), Helper::LoggingProperties::NAME.data(), __FILE__, __LINE__) #define LOG(level) Helper::Logger(level, __func__, Helper::LoggingProperties::FILE.data(), Helper::LoggingProperties::NAME.data(), __FILE__, __LINE__)
#define LOGN(name, level) Helper::Logger(level, Helper::LoggingProperties::FILE.data(), name, __FILE__, __LINE__) #define LOGN(name, level) Helper::Logger(level, __func__, Helper::LoggingProperties::FILE.data(), name, __FILE__, __LINE__)
#define LOGNF(name, file, level) Helper::Logger(level, file, name, __FILE__, __LINE__) #define LOGNF(name, file, level) Helper::Logger(level, file, name, __FILE__, __LINE__)
#define LOG_IF(level, condition) \ #define LOG_IF(level, condition) \
if (condition) Helper::Logger(level, Helper::LoggingProperties::FILE.data(), Helper::LoggingProperties::NAME.data(), __FILE__, __LINE__) if (condition) Helper::Logger(level, __func__, Helper::LoggingProperties::FILE.data(), Helper::LoggingProperties::NAME.data(), __FILE__, __LINE__)
#define LOGN_IF(name, level, condition) \ #define LOGN_IF(name, level, condition) \
if (condition) Helper::Logger(level, Helper::LoggingProperties::FILE.data(), name, __FILE__, __LINE__) if (condition) Helper::Logger(level, __func__, Helper::LoggingProperties::FILE.data(), name, __FILE__, __LINE__)
#define LOGNF_IF(name, file, level, condition) \ #define LOGNF_IF(name, file, level, condition) \
if (condition) Helper::Logger(level, file, name, __FILE__, __LINE__) if (condition) Helper::Logger(level, __func__, file, name, __FILE__, __LINE__)
#endif // #ifndef LIBHELPER_LIB_HPP #endif // #ifndef LIBHELPER_LIB_HPP

View File

@@ -25,11 +25,9 @@
static void __create_log_file(const char* file) static void __create_log_file(const char* file)
{ {
remove(file);
int fd = open(file, O_WRONLY | O_TRUNC, DEFAULT_EXTENDED_FILE_PERMS); int fd = open(file, O_WRONLY | O_TRUNC, DEFAULT_EXTENDED_FILE_PERMS);
if (fd == -1) { if (fd != -1) close(fd);
fd = open(file, O_WRONLY | O_CREAT, DEFAULT_EXTENDED_FILE_PERMS);
if (fd != -1) close(fd);
} else if (fd != -1) close(fd);
} }
namespace Helper { namespace Helper {
@@ -50,19 +48,20 @@ const char* Error::what() const noexcept
return _message.data(); return _message.data();
} }
Logger::Logger(LogLevels level, const char* file, const char* name, const char* sfile, int line) : _level(level), _logFile(file), _program_name(name), _file(sfile), _line(line) {} Logger::Logger(LogLevels level, const char* func, const char* file, const char* name, const char* sfile, int line) : _level(level), _funcname(func), _logFile(file), _program_name(name), _file(sfile), _line(line) {}
Logger::~Logger() Logger::~Logger()
{ {
if (LoggingProperties::DISABLE) return; if (LoggingProperties::DISABLE) return;
char str[1024]; char str[1024];
snprintf(str, sizeof(str), "<%c> [ <prog %s> <on %s:%d> %s %s] %s", snprintf(str, sizeof(str), "<%c> [ <prog %s> <on %s:%d> %s %s] %s(): %s",
(char)_level, (char)_level,
_program_name, _program_name,
basename((char*)_file), basename((char*)_file),
_line, _line,
currentDate().data(), currentDate().data(),
currentTime().data(), currentTime().data(),
_funcname,
_oss.str().data()); _oss.str().data());
if (!isExists(_logFile)) __create_log_file(_logFile); if (!isExists(_logFile)) __create_log_file(_logFile);

View File

@@ -41,20 +41,20 @@ namespace Helper {
bool writeFile(const std::string_view file, const std::string_view text) bool writeFile(const std::string_view file, const std::string_view text)
{ {
LOGN(HELPER, INFO) << __func__ << "(): write \"" << text << "\" to " << file << "requested." << std::endl; LOGN(HELPER, INFO) << "write \"" << text << "\" to " << file << "requested." << std::endl;
FILE* fp = open_file(file, "a"); FILE* fp = open_file(file, "a");
if (fp == nullptr) return false; if (fp == nullptr) return false;
fprintf(fp, "%s", text.data()); fprintf(fp, "%s", text.data());
fclose(fp); fclose(fp);
LOGN(HELPER, INFO) << __func__ << "(): write " << file << " successfull." << std::endl; LOGN(HELPER, INFO) << "write " << file << " successfull." << std::endl;
return true; return true;
} }
std::optional<std::string> readFile(const std::string_view file) std::optional<std::string> readFile(const std::string_view file)
{ {
LOGN(HELPER, INFO) << __func__ << "(): read " << file << " requested." << std::endl; LOGN(HELPER, INFO) << "read " << file << " requested." << std::endl;
FILE* fp = open_file(file, "r"); FILE* fp = open_file(file, "r");
if (fp == nullptr) return std::nullopt; if (fp == nullptr) return std::nullopt;
@@ -63,13 +63,13 @@ std::optional<std::string> readFile(const std::string_view file)
while (fgets(buffer, sizeof(buffer), fp)) str += buffer; while (fgets(buffer, sizeof(buffer), fp)) str += buffer;
fclose(fp); fclose(fp);
LOGN(HELPER, INFO) << __func__ << "(): read " << file << " successfull, readed text: \"" << str << "\"" << std::endl; LOGN(HELPER, INFO) << "read " << file << " successfull, readed text: \"" << str << "\"" << std::endl;
return str; return str;
} }
bool copyFile(const std::string_view file, const std::string_view dest) bool copyFile(const std::string_view file, const std::string_view dest)
{ {
LOGN(HELPER, INFO) << __func__ << "(): copy " << file << " to " << dest << " requested." << std::endl; LOGN(HELPER, INFO) << "copy " << file << " to " << dest << " requested." << std::endl;
int src_fd = open(file.data(), O_RDONLY); int src_fd = open(file.data(), O_RDONLY);
if (src_fd == - 1) { if (src_fd == - 1) {
@@ -103,20 +103,20 @@ bool copyFile(const std::string_view file, const std::string_view dest)
return false; return false;
} }
LOGN(HELPER, INFO) << __func__ << "(); copy " << file << " to " << dest << " successfull." << std::endl; LOGN(HELPER, INFO) << "copy " << file << " to " << dest << " successfull." << std::endl;
return true; return true;
} }
bool makeDirectory(const std::string_view path) bool makeDirectory(const std::string_view path)
{ {
if (isExists(path)) return false; if (isExists(path)) return false;
LOGN(HELPER, INFO) << __func__ << "(): trying making directory: " << path << std::endl; LOGN(HELPER, INFO) << "trying making directory: " << path << std::endl;
return (mkdir(path.data(), DEFAULT_DIR_PERMS) == 0) ? true : false; return (mkdir(path.data(), DEFAULT_DIR_PERMS) == 0) ? true : false;
} }
bool makeRecursiveDirectory(const std::string_view paths) bool makeRecursiveDirectory(const std::string_view paths)
{ {
LOGN(HELPER, INFO) << __func__ << "(): make recursive directory requested: " << paths << std::endl; LOGN(HELPER, INFO) << "make recursive directory requested: " << paths << std::endl;
char tmp[PATH_MAX], *p; char tmp[PATH_MAX], *p;
size_t len; size_t len;
@@ -146,13 +146,13 @@ bool makeRecursiveDirectory(const std::string_view paths)
} }
} }
LOGN(HELPER, INFO) << __func__ << "(): " << paths << " successfully created." << std::endl; LOGN(HELPER, INFO) << "" << paths << " successfully created." << std::endl;
return true; return true;
} }
bool createFile(const std::string_view path) bool createFile(const std::string_view path)
{ {
LOGN(HELPER, INFO) << __func__ << "(): create file request: " << path << std::endl; LOGN(HELPER, INFO) << "create file request: " << path << std::endl;
if (isExists(path)) { if (isExists(path)) {
throw Error("%s: is exists", path.data()); throw Error("%s: is exists", path.data());
@@ -166,35 +166,35 @@ bool createFile(const std::string_view path)
} }
close(fd); close(fd);
LOGN(HELPER, INFO) << __func__ << "(): create file \"" << path << "\" successfull." << std::endl; LOGN(HELPER, INFO) << "create file \"" << path << "\" successfull." << std::endl;
return true; return true;
} }
bool createSymlink(const std::string_view entry1, const std::string_view entry2) bool createSymlink(const std::string_view entry1, const std::string_view entry2)
{ {
LOGN(HELPER, INFO) << __func__ << "(): symlink \"" << entry1 << "\" to \"" << entry2 << "\" requested." << std::endl; LOGN(HELPER, INFO) << "symlink \"" << entry1 << "\" to \"" << entry2 << "\" requested." << std::endl;
int ret = symlink(entry1.data(), entry2.data()); int ret = symlink(entry1.data(), entry2.data());
if (ret != 0) if (ret != 0)
throw Error("Cannot symlink %s: %s", entry2.data(), strerror(errno)); throw Error("Cannot symlink %s: %s", entry2.data(), strerror(errno));
LOGN_IF(HELPER, INFO, ret == 0) << __func__ << "(): \"" << entry1 << "\" symlinked to \"" << entry2 << "\" successfully." << std::endl; LOGN_IF(HELPER, INFO, ret == 0) << "\"" << entry1 << "\" symlinked to \"" << entry2 << "\" successfully." << std::endl;
return (ret == 0); return (ret == 0);
} }
bool eraseEntry(const std::string_view entry) bool eraseEntry(const std::string_view entry)
{ {
LOGN(HELPER, INFO) << __func__ << "(): erase \"" << entry << "\" requested." << std::endl; LOGN(HELPER, INFO) << "erase \"" << entry << "\" requested." << std::endl;
int ret = remove(entry.data()); int ret = remove(entry.data());
if (ret != 0) if (ret != 0)
throw Error("Cannot remove %s: %s", entry.data(), strerror(errno)); throw Error("Cannot remove %s: %s", entry.data(), strerror(errno));
LOGN_IF(HELPER, INFO, ret == 0) << __func__ << "(): \"" << entry << "\" erased successfully." << std::endl; LOGN_IF(HELPER, INFO, ret == 0) << "\"" << entry << "\" erased successfully." << std::endl;
return (ret == 0); return (ret == 0);
} }
bool eraseDirectoryRecursive(const std::string_view directory) bool eraseDirectoryRecursive(const std::string_view directory)
{ {
LOGN(HELPER, INFO) << __func__ << "(): erase recursive requested: " << directory << std::endl; LOGN(HELPER, INFO) << "erase recursive requested: " << directory << std::endl;
struct stat buf; struct stat buf;
struct dirent *entry; struct dirent *entry;
@@ -239,13 +239,13 @@ bool eraseDirectoryRecursive(const std::string_view directory)
return false; return false;
} }
LOGN(HELPER, INFO) << __func__ << "(): \"" << directory << "\" successfully erased." << std::endl; LOGN(HELPER, INFO) << "\"" << directory << "\" successfully erased." << std::endl;
return true; return true;
} }
std::string readSymlink(const std::string_view entry) std::string readSymlink(const std::string_view entry)
{ {
LOGN(HELPER, INFO) << __func__ << "(): read symlink request: " << entry << std::endl; LOGN(HELPER, INFO) << "read symlink request: " << entry << std::endl;
char target[PATH_MAX]; char target[PATH_MAX];
ssize_t len = readlink(entry.data(), target, (sizeof(target) - 1)); ssize_t len = readlink(entry.data(), target, (sizeof(target) - 1));
@@ -255,13 +255,13 @@ std::string readSymlink(const std::string_view entry)
} }
target[len] = '\0'; target[len] = '\0';
LOGN(HELPER, INFO) << __func__ << "(): \"" << entry << "\" symlink to \"" << target << "\"" << std::endl; LOGN(HELPER, INFO) << "\"" << entry << "\" symlink to \"" << target << "\"" << std::endl;
return target; return target;
} }
size_t fileSize(const std::string_view file) size_t fileSize(const std::string_view file)
{ {
LOGN(HELPER, INFO) << __func__ << "(): get file size request: " << file << std::endl; LOGN(HELPER, INFO) << "get file size request: " << file << std::endl;
struct stat st; struct stat st;
if (stat(file.data(), &st) != 0) return false; if (stat(file.data(), &st) != 0) return false;
return static_cast<size_t>(st.st_size); return static_cast<size_t>(st.st_size);

View File

@@ -27,7 +27,7 @@ namespace Helper {
std::optional<std::string> sha256Of(const std::string_view path) std::optional<std::string> sha256Of(const std::string_view path)
{ {
LOGN(HELPER, INFO) << __func__ << "(): get sha256 of \"" << path << "\" request. Getting full path (if input is link and exists)." << std::endl; LOGN(HELPER, INFO) << "get sha256 of \"" << path << "\" request. Getting full path (if input is link and exists)." << std::endl;
std::string fp = (isLink(path)) ? readSymlink(path) : std::string(path); std::string fp = (isLink(path)) ? readSymlink(path) : std::string(path);
if (!fileIsExists(fp)) { if (!fileIsExists(fp)) {
@@ -43,13 +43,13 @@ std::optional<std::string> sha256Of(const std::string_view path)
std::vector<unsigned char> hash(picosha2::k_digest_size); std::vector<unsigned char> hash(picosha2::k_digest_size);
picosha2::hash256(fp, hash.begin(), hash.end()); picosha2::hash256(fp, hash.begin(), hash.end());
LOGN(HELPER, INFO) << __func__ << "(): get sha256 of \"" << path << "\" successfull." << std::endl; LOGN(HELPER, INFO) << "get sha256 of \"" << path << "\" successfull." << std::endl;
return picosha2::bytes_to_hex_string(hash.begin(), hash.end()); return picosha2::bytes_to_hex_string(hash.begin(), hash.end());
} }
bool sha256Compare(const std::string_view file1, const std::string_view file2) bool sha256Compare(const std::string_view file1, const std::string_view file2)
{ {
LOGN(HELPER, INFO) << __func__ << "(): comparing sha256 signatures of input files." << std::endl; LOGN(HELPER, INFO) << "comparing sha256 signatures of input files." << std::endl;
auto f1 = sha256Of(file1); auto f1 = sha256Of(file1);
auto f2 = sha256Of(file2); auto f2 = sha256Of(file2);
if (f1->empty() || f2->empty()) return false; if (f1->empty() || f2->empty()) return false;

View File

@@ -65,13 +65,13 @@ void setLoggingState(int state)
bool runCommand(const std::string_view cmd) bool runCommand(const std::string_view cmd)
{ {
LOGN(HELPER, INFO) << __func__ << "(): run command request: " << cmd << std::endl; LOGN(HELPER, INFO) << "run command request: " << cmd << std::endl;
return (system(cmd.data()) == 0) ? true : false; return (system(cmd.data()) == 0) ? true : false;
} }
bool confirmPropt(const std::string_view message) bool confirmPropt(const std::string_view message)
{ {
LOGN(HELPER, INFO) << __func__ << "(): create confirm propt request. Creating." << std::endl; LOGN(HELPER, INFO) << "create confirm propt request. Creating." << std::endl;
char p; char p;
printf("%s [ y / n ]: ", message.data()); printf("%s [ y / n ]: ", message.data());
@@ -122,7 +122,7 @@ std::string currentTime()
std::string runCommandWithOutput(const std::string_view cmd) std::string runCommandWithOutput(const std::string_view cmd)
{ {
LOGN(HELPER, INFO) << __func__ << "(): run command and catch out request: " << cmd << std::endl; LOGN(HELPER, INFO) << "run command and catch out request: " << cmd << std::endl;
FILE* pipe = popen(cmd.data(), "r"); FILE* pipe = popen(cmd.data(), "r");
if (!pipe) { if (!pipe) {

View File

@@ -55,14 +55,14 @@ Map_t basic_partition_map_builder::_build_map(std::string_view path, bool logica
return a.path().filename() < b.path().filename(); return a.path().filename() < b.path().filename();
}); });
LOGN_IF(MAP, WARNING, entries.empty()) << __func__ << "(): " << path << "is exists but generated vector is empty (std::vector<std::filesystem::directory_entry>)." << std::endl; LOGN_IF(MAP, WARNING, entries.empty()) << "" << path << "is exists but generated vector is empty (std::vector<std::filesystem::directory_entry>)." << std::endl;
for (const auto& entry : entries) { for (const auto& entry : entries) {
if (entry.path().filename() != "by-uuid" if (entry.path().filename() != "by-uuid"
&& std::string(entry.path()).find("com.") == std::string::npos) && std::string(entry.path()).find("com.") == std::string::npos)
map.insert(entry.path().filename().string(), _get_size(entry.path()), logical); map.insert(entry.path().filename().string(), _get_size(entry.path()), logical);
} }
LOGN(MAP, INFO) << std::boolalpha << __func__ << "(): Map generated successfully. is_logical_map=" << logical << std::endl; LOGN(MAP, INFO) << std::boolalpha << "Map generated successfully. is_logical_map=" << logical << std::endl;
return map; return map;
} }
@@ -81,13 +81,16 @@ uint64_t basic_partition_map_builder::_get_size(const std::string path)
{ {
std::string real = std::filesystem::read_symlink(path); std::string real = std::filesystem::read_symlink(path);
int fd = open(real.data(), O_RDONLY); int fd = open(real.data(), O_RDONLY);
if (fd < 0) if (fd < 0) {
throw Error("Cannot open %s: %s", real.data(), strerror(errno)); LOGN(MAP, ERROR) << "Cannot open " << real << ": " << strerror(errno) << std::endl;
return 0;
}
uint64_t size = 0; uint64_t size = 0;
if (ioctl(fd, BLKGETSIZE64, &size) != 0) { if (ioctl(fd, BLKGETSIZE64, &size) != 0) {
close(fd); close(fd);
throw Error("ioctl() process failed for %s: %s", real.data(), strerror(errno)); LOGN(MAP, ERROR) << "ioctl() process failed for " << real << ": " << strerror(errno) << std::endl;
return 0;
} }
close(fd); close(fd);
@@ -96,7 +99,7 @@ uint64_t basic_partition_map_builder::_get_size(const std::string path)
basic_partition_map_builder::basic_partition_map_builder() basic_partition_map_builder::basic_partition_map_builder()
{ {
LOGN(MAP, INFO) << __func__ << "(): default constructor called. Starting build." << std::endl; LOGN(MAP, INFO) << "default constructor called. Starting build." << std::endl;
for (const auto& path : defaultEntryList) { for (const auto& path : defaultEntryList) {
if (std::filesystem::exists(path)) { if (std::filesystem::exists(path)) {
@@ -112,16 +115,16 @@ basic_partition_map_builder::basic_partition_map_builder()
} }
if (_current_map.empty()) if (_current_map.empty())
throw Error("Cannot build map by any default search entry."); LOGN(MAP, ERROR) << "Cannot build map by any default search entry." << std::endl;
LOGN(MAP, INFO) << __func__ << "(): default constructor successfully ended work." << std::endl; LOGN(MAP, INFO) << "default constructor successfully ended work." << std::endl;
_insert_logicals(_build_map("/dev/block/mapper", true)); _insert_logicals(_build_map("/dev/block/mapper", true));
_map_builded = true; _map_builded = true;
} }
basic_partition_map_builder::basic_partition_map_builder(const std::string_view path) basic_partition_map_builder::basic_partition_map_builder(const std::string_view path)
{ {
LOGN(MAP, INFO) << __func__ << "(): argument-based constructor called. Starting build." << std::endl; LOGN(MAP, INFO) << "argument-based constructor called. Starting build." << std::endl;
if (std::filesystem::exists(path)) { if (std::filesystem::exists(path)) {
_is_real_block_dir(path); _is_real_block_dir(path);
@@ -131,7 +134,7 @@ basic_partition_map_builder::basic_partition_map_builder(const std::string_view
} else } else
throw Error("Cannot find directory: %s. Cannot build partition map!", path.data()); throw Error("Cannot find directory: %s. Cannot build partition map!", path.data());
LOGN(MAP, INFO) << __func__ << "(): argument-based constructor successfully ended work." << std::endl; LOGN(MAP, INFO) << "argument-based constructor successfully ended work." << std::endl;
_insert_logicals(_build_map("/dev/block/mapper", true)); _insert_logicals(_build_map("/dev/block/mapper", true));
_map_builded = true; _map_builded = true;
} }
@@ -158,7 +161,7 @@ void basic_partition_map_builder::clear()
bool basic_partition_map_builder::readDirectory(const std::string_view path) bool basic_partition_map_builder::readDirectory(const std::string_view path)
{ {
_map_builded = false; _map_builded = false;
LOGN(MAP, INFO) << __func__ << "(): read " << path << " directory request." << std::endl; LOGN(MAP, INFO) << "read " << path << " directory request." << std::endl;
if (std::filesystem::exists(path)) { if (std::filesystem::exists(path)) {
if (!_is_real_block_dir(path)) return false; if (!_is_real_block_dir(path)) return false;
@@ -170,7 +173,7 @@ bool basic_partition_map_builder::readDirectory(const std::string_view path)
} else } else
throw Error("Cannot find directory: %s. Cannot build partition map!", path.data()); throw Error("Cannot find directory: %s. Cannot build partition map!", path.data());
LOGN(MAP, INFO) << __func__ << "(): read " << path << " successfull." << std::endl; LOGN(MAP, INFO) << "read " << path << " successfull." << std::endl;
_insert_logicals(_build_map("/dev/block/mapper", true)); _insert_logicals(_build_map("/dev/block/mapper", true));
_map_builded = true; _map_builded = true;
return true; return true;

View File

@@ -142,16 +142,16 @@ bool basic_partition_map::insert(const std::string name, uint64_t size, bool log
if (_count == _capacity) _resize_map(); if (_count == _capacity) _resize_map();
_data[_count++] = {name, {size, logical}}; _data[_count++] = {name, {size, logical}};
LOGN(MAP, INFO) << std::boolalpha << __func__ << "(): partition " << name << " inserted (size=" << size << ", is_logical=" << logical << ")." << std::endl; LOGN(MAP, INFO) << std::boolalpha << "partition " << name << " inserted (size=" << size << ", is_logical=" << logical << ")." << std::endl;
return true; return true;
} }
void basic_partition_map::merge(const basic_partition_map& map) void basic_partition_map::merge(const basic_partition_map& map)
{ {
LOGN(MAP, INFO) << __func__ << "(): map merge request." << std::endl; LOGN(MAP, INFO) << "map merge request." << std::endl;
for (const auto& [name, props] : map) for (const auto& [name, props] : map)
insert(name, props.size, props.isLogical); insert(name, props.size, props.isLogical);
LOGN(MAP, INFO) << __func__ << "(): map merged successfully." << std::endl; LOGN(MAP, INFO) << "map merged successfully." << std::endl;
} }
uint64_t basic_partition_map::get_size(const std::string_view name) const uint64_t basic_partition_map::get_size(const std::string_view name) const
@@ -206,7 +206,7 @@ bool basic_partition_map::empty() const
void basic_partition_map::clear() void basic_partition_map::clear()
{ {
LOGN(MAP, INFO) << __func__ << "(): map clean requested. Map is empty now." << std::endl; LOGN(MAP, INFO) << "map clean requested. Map is empty now." << std::endl;
delete[] _data; delete[] _data;
_count = 0; _count = 0;
_capacity = 6; _capacity = 6;