pmt: The basis of the system for adding features was created and improvements were made.
- The basic header contents of the system, designed to easily add features, were written. - The [CLI11](https://github.com/CLIUtils/CLI11) project was included to provide a better experience for the project. - Improved logging system. - Unnecessary code cleaned.
This commit is contained in:
11527
include/CLI/CLI11.hpp
Normal file
11527
include/CLI/CLI11.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,9 +22,60 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <libpartition_map/lib.hpp>
|
|
||||||
#include <libhelper/lib.hpp>
|
#include <libhelper/lib.hpp>
|
||||||
|
#include <libpartition_map/lib.hpp>
|
||||||
|
|
||||||
namespace PartitionManager {} // namespace PartitionManager
|
#ifdef NEED_BASIC_FUNCTION_CLASSES
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignore "-Wdeprecated-declarations"
|
||||||
|
#include <CLI/CLI11.hpp>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif // #ifdef NEED_BASIC_FUNCTION_CLASSES
|
||||||
|
|
||||||
|
namespace PartitionManager {
|
||||||
|
|
||||||
|
#ifdef NEED_BASIC_FUNCTION_CLASSES
|
||||||
|
class basic_function {
|
||||||
|
/**
|
||||||
|
* Example variables for writing your function:
|
||||||
|
* private:
|
||||||
|
* CLI::App _cmd* = nullptr;
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
virtual bool init(CLI::App& _app) = 0;
|
||||||
|
virtual bool run() = 0;
|
||||||
|
virtual const char* name() = 0;
|
||||||
|
virtual ~basic_function() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class basic_function_manager {
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<basic_function>> _functions;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void registerFunction(std::unique_ptr<basic_function> _func, CLI::App& _app);
|
||||||
|
|
||||||
|
void startUsedFunctions();
|
||||||
|
};
|
||||||
|
|
||||||
|
using FunctionBase = basic_function;
|
||||||
|
using FunctionManager = basic_function_manager;
|
||||||
|
|
||||||
|
#endif // #ifdef NEED_BASIC_FUNCTION_CLASSES
|
||||||
|
|
||||||
|
namespace Variables {
|
||||||
|
|
||||||
|
extern PartitionMap::BuildMap PartMap;
|
||||||
|
|
||||||
|
} // namespace Variables
|
||||||
|
|
||||||
|
int Main(int argc, char** argv);
|
||||||
|
|
||||||
|
std::string getLibVersion();
|
||||||
|
std::string getAppVersion();
|
||||||
|
|
||||||
|
} // namespace PartitionManager
|
||||||
|
|
||||||
#endif // #ifndef LIBPMT_LIB_HPP
|
#endif // #ifndef LIBPMT_LIB_HPP
|
||||||
|
|||||||
0
src/Lib.cpp
Normal file
0
src/Lib.cpp
Normal file
0
src/Main.cpp
Normal file
0
src/Main.cpp
Normal file
66
src/functions/functions.hpp
Normal file
66
src/functions/functions.hpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NEED_BASIC_FUNCTION_CLASSES
|
||||||
|
#include <libpmt/lib.hpp>
|
||||||
|
|
||||||
|
namespace PartitionManager {
|
||||||
|
|
||||||
|
// Back-up function
|
||||||
|
class backupFunction : public PartitionManager::FunctionBase {
|
||||||
|
private:
|
||||||
|
CLI::App* _cmd = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool init(CLI::App& _app) override;
|
||||||
|
bool run() override;
|
||||||
|
const char* name() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Image flasher function
|
||||||
|
class flashFunction : public PartitionManager::FunctionBase {
|
||||||
|
private:
|
||||||
|
CLI::App* _cmd = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool init(CLI::App& _app) override;
|
||||||
|
bool run() override;
|
||||||
|
const char* name() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Eraser function (only the partition content is cleared)
|
||||||
|
class eraseFunction : public PartitionManager::FunctionBase {
|
||||||
|
private:
|
||||||
|
CLI::App* _cmd = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool init(CLI::App& _app) override;
|
||||||
|
bool run() override;
|
||||||
|
const char* name() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Partition size getter function
|
||||||
|
class partitionSizeFunction : public PartitionManager::FunctionBase {
|
||||||
|
private:
|
||||||
|
CLI::App* _cmd = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool init(CLI::App& _app) override;
|
||||||
|
bool run() override;
|
||||||
|
const char* name() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace PartitionManager
|
||||||
@@ -26,10 +26,10 @@
|
|||||||
#ifndef ONLY_HELPER_MACROS
|
#ifndef ONLY_HELPER_MACROS
|
||||||
|
|
||||||
enum LogLevels {
|
enum LogLevels {
|
||||||
INFO = (int)'I',
|
INFO = (int)'I',
|
||||||
WARNING = (int)'W',
|
WARNING = (int)'W',
|
||||||
ERROR = (int)'E',
|
ERROR = (int)'E',
|
||||||
ABORT = (int)'A'
|
ABORT = (int)'A'
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr mode_t DEFAULT_FILE_PERMS = 0644;
|
constexpr mode_t DEFAULT_FILE_PERMS = 0644;
|
||||||
@@ -60,18 +60,6 @@ public:
|
|||||||
Logger& operator<<(std::ostream& (*msg)(std::ostream&));
|
Logger& operator<<(std::ostream& (*msg)(std::ostream&));
|
||||||
};
|
};
|
||||||
|
|
||||||
class LoggingProperties {
|
|
||||||
public:
|
|
||||||
static std::string_view FILE, NAME;
|
|
||||||
static bool PRINT;
|
|
||||||
|
|
||||||
static void set(std::string_view name, std::string_view file);
|
|
||||||
static void setProgramName(std::string_view name);
|
|
||||||
static void setLogFile(std::string_view file);
|
|
||||||
static void setPrinting(int state);
|
|
||||||
static void reset();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Throwable error class
|
// Throwable error class
|
||||||
class Error : public std::exception {
|
class Error : public std::exception {
|
||||||
private:
|
private:
|
||||||
@@ -83,6 +71,20 @@ public:
|
|||||||
const char* what() const noexcept override;
|
const char* what() const noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace LoggingProperties {
|
||||||
|
|
||||||
|
extern std::string_view FILE, NAME;
|
||||||
|
extern bool PRINT, DISABLE;
|
||||||
|
|
||||||
|
void set(std::string_view name, std::string_view file);
|
||||||
|
void setProgramName(std::string_view name);
|
||||||
|
void setLogFile(std::string_view file);
|
||||||
|
void setPrinting(int state);
|
||||||
|
void setLoggingState(int state); // Disable/enable logginf
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
} // namespace LoggingProperties
|
||||||
|
|
||||||
// Checkers
|
// Checkers
|
||||||
bool hasSuperUser();
|
bool hasSuperUser();
|
||||||
bool isExists(const std::string_view entry);
|
bool isExists(const std::string_view entry);
|
||||||
@@ -135,10 +137,15 @@ std::string getLibVersion();
|
|||||||
|
|
||||||
#endif // #ifndef ONLY_HELPER_MACROS
|
#endif // #ifndef ONLY_HELPER_MACROS
|
||||||
|
|
||||||
|
#define HELPER "libhelper"
|
||||||
|
|
||||||
#define KB(x) (x * 1024) // KB(8) = 8192 (8 * 1024)
|
#define KB(x) (x * 1024) // KB(8) = 8192 (8 * 1024)
|
||||||
#define MB(x) (KB(x) * 1024) // MB(4) = 4194304 (KB(4) * 1024)
|
#define MB(x) (KB(x) * 1024) // MB(4) = 4194304 (KB(4) * 1024)
|
||||||
#define GB(x) (MB(x) * 1024) // GB(1) = 1073741824 (MB(1) * 1024)
|
#define GB(x) (MB(x) * 1024) // GB(1) = 1073741824 (MB(1) * 1024)
|
||||||
|
|
||||||
|
#define TO_MB(x) (x / 1024) // TO_MB(2048) (2048 / 1024)
|
||||||
|
#define TO_GB(x) (TO_GB(x) / 1024) // TO_GB(1048576) (TO_MB(1048576) / 1024)
|
||||||
|
|
||||||
#define STYLE_RESET "\033[0m"
|
#define STYLE_RESET "\033[0m"
|
||||||
#define BOLD "\033[1m"
|
#define BOLD "\033[1m"
|
||||||
#define FAINT "\033[2m"
|
#define FAINT "\033[2m"
|
||||||
@@ -178,5 +185,14 @@ std::string getLibVersion();
|
|||||||
#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, 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 LOGNF(name, file, level) Helper::Logger(level, file, name, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define LOG_IF(level, condition) \
|
||||||
|
if (condition) Helper::Logger(level, Helper::LoggingProperties::FILE.data(), Helper::LoggingProperties::NAME.data(), __FILE__, __LINE__)
|
||||||
|
#define LOGN_IF(name, level, condition) \
|
||||||
|
if (condition) Helper::Logger(level, Helper::LoggingProperties::FILE.data(), name, __FILE__, __LINE__)
|
||||||
|
#define LOGNF_IF(name, file, level, condition) \
|
||||||
|
if (condition) Helper::Logger(level, file, name, __FILE__, __LINE__)
|
||||||
|
|
||||||
#endif // #ifndef LIBHELPER_LIB_HPP
|
#endif // #ifndef LIBHELPER_LIB_HPP
|
||||||
|
|||||||
@@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
namespace Helper {
|
namespace Helper {
|
||||||
|
|
||||||
std::string_view LoggingProperties::FILE = "last_logs.log", LoggingProperties::NAME = "main";
|
|
||||||
bool LoggingProperties::PRINT = NO;
|
|
||||||
|
|
||||||
Error::Error(const char* format, ...)
|
Error::Error(const char* format, ...)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@@ -36,6 +33,7 @@ Error::Error(const char* format, ...)
|
|||||||
vsnprintf(buf, sizeof(buf), format, args);
|
vsnprintf(buf, sizeof(buf), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
_message = std::string(buf);
|
_message = std::string(buf);
|
||||||
|
LOGN(HELPER, ERROR) << "Error::Error(): " << _message << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Error::what() const noexcept
|
const char* Error::what() const noexcept
|
||||||
@@ -47,6 +45,7 @@ Logger::Logger(LogLevels level, const char* file, const char* name, const char*
|
|||||||
|
|
||||||
Logger::~Logger()
|
Logger::~Logger()
|
||||||
{
|
{
|
||||||
|
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",
|
||||||
(char)_level,
|
(char)_level,
|
||||||
@@ -58,15 +57,14 @@ Logger::~Logger()
|
|||||||
_oss.str().data());
|
_oss.str().data());
|
||||||
|
|
||||||
if (!isExists(_logFile)) createFile(_logFile);
|
if (!isExists(_logFile)) createFile(_logFile);
|
||||||
|
|
||||||
FILE* fp = fopen(_logFile, "a");
|
FILE* fp = fopen(_logFile, "a");
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
fprintf(fp, "%s", str);
|
fprintf(fp, "%s", str);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
if (LoggingProperties::PRINT) printf("%s\n", str);
|
|
||||||
|
|
||||||
if (_level == ERROR) exit(1);
|
if (LoggingProperties::PRINT) printf("%s\n", str);
|
||||||
else if (_level == ABORT) abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger& Logger::operator<<(std::ostream& (*msg)(std::ostream&))
|
Logger& Logger::operator<<(std::ostream& (*msg)(std::ostream&))
|
||||||
@@ -75,22 +73,4 @@ Logger& Logger::operator<<(std::ostream& (*msg)(std::ostream&))
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoggingProperties::reset()
|
|
||||||
{
|
|
||||||
FILE = "last_logs.log";
|
|
||||||
NAME = "main";
|
|
||||||
PRINT = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoggingProperties::set(std::string_view file, std::string_view name)
|
|
||||||
{
|
|
||||||
FILE = file;
|
|
||||||
NAME = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoggingProperties::setProgramName(std::string_view name) { NAME = name; }
|
|
||||||
void LoggingProperties::setLogFile(std::string_view file) { FILE = file; }
|
|
||||||
void LoggingProperties::setPrinting(int state) { PRINT = state; }
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Helper
|
} // namespace Helper
|
||||||
|
|||||||
@@ -41,17 +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;
|
||||||
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;
|
||||||
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;
|
||||||
FILE* fp = open_file(file, "r");
|
FILE* fp = open_file(file, "r");
|
||||||
if (fp == nullptr) return std::nullopt;
|
if (fp == nullptr) return std::nullopt;
|
||||||
|
|
||||||
@@ -60,11 +63,14 @@ 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;
|
||||||
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;
|
||||||
|
|
||||||
int src_fd = open(file.data(), O_RDONLY);
|
int src_fd = open(file.data(), O_RDONLY);
|
||||||
if (src_fd == - 1) {
|
if (src_fd == - 1) {
|
||||||
throw Error("Cannot open %s: %s", file.data(), strerror(errno));
|
throw Error("Cannot open %s: %s", file.data(), strerror(errno));
|
||||||
@@ -97,17 +103,21 @@ 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;
|
||||||
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;
|
||||||
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;
|
||||||
|
|
||||||
char tmp[PATH_MAX], *p;
|
char tmp[PATH_MAX], *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
@@ -136,11 +146,14 @@ bool makeRecursiveDirectory(const std::string_view paths)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGN(HELPER, INFO) << __func__ << "(): " << 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;
|
||||||
|
|
||||||
if (isExists(path)) {
|
if (isExists(path)) {
|
||||||
throw Error("%s: is exists", path.data());
|
throw Error("%s: is exists", path.data());
|
||||||
return false;
|
return false;
|
||||||
@@ -153,29 +166,35 @@ bool createFile(const std::string_view path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
LOGN(HELPER, INFO) << __func__ << "(): 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;
|
||||||
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;
|
||||||
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;
|
||||||
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;
|
||||||
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;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
|
||||||
@@ -220,11 +239,13 @@ bool eraseDirectoryRecursive(const std::string_view directory)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGN(HELPER, INFO) << __func__ << "(): \"" << 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;
|
||||||
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));
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
@@ -233,11 +254,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;
|
||||||
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;
|
||||||
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);
|
||||||
|
|||||||
@@ -27,6 +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." << std::endl;
|
||||||
if (!fileIsExists(path)) {
|
if (!fileIsExists(path)) {
|
||||||
throw Error("Is not exists or not file: %s", path.data());
|
throw Error("Is not exists or not file: %s", path.data());
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -40,14 +41,17 @@ 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(path, hash.begin(), hash.end());
|
picosha2::hash256(path, hash.begin(), hash.end());
|
||||||
|
LOGN(HELPER, INFO) << __func__ << "(): 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;
|
||||||
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;
|
||||||
|
LOGN_IF(HELPER, INFO, *f1 == *f2) << "(): input files is contains same sha256 signature." << std::endl;
|
||||||
return (*f1 == *f2);
|
return (*f1 == *f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -27,14 +28,50 @@
|
|||||||
#include <generated/buildInfo.hpp>
|
#include <generated/buildInfo.hpp>
|
||||||
|
|
||||||
namespace Helper {
|
namespace Helper {
|
||||||
|
namespace LoggingProperties {
|
||||||
|
|
||||||
|
std::string_view FILE = "last_logs.log", NAME = "main";
|
||||||
|
bool PRINT = NO, DISABLE = NO;
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
FILE = "last_logs.log";
|
||||||
|
NAME = "main";
|
||||||
|
PRINT = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(std::string_view file, std::string_view name)
|
||||||
|
{
|
||||||
|
if (file.data() != nullptr) FILE = file;
|
||||||
|
if (name.data() != nullptr) NAME = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setProgramName(std::string_view name) { NAME = name; }
|
||||||
|
void setLogFile(std::string_view file) { FILE = file; }
|
||||||
|
|
||||||
|
void setPrinting(int state)
|
||||||
|
{
|
||||||
|
if (state == 1 || state == 0) PRINT = state;
|
||||||
|
else PRINT = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLoggingState(int state)
|
||||||
|
{
|
||||||
|
if (state == 1 || state == 0) DISABLE = state;
|
||||||
|
else DISABLE = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LoggingProperties
|
||||||
|
|
||||||
bool runCommand(const std::string_view cmd)
|
bool runCommand(const std::string_view cmd)
|
||||||
{
|
{
|
||||||
|
LOGN(HELPER, INFO) << __func__ << "(): 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;
|
||||||
char p;
|
char p;
|
||||||
|
|
||||||
printf("%s [ y / n ]: ", message.data());
|
printf("%s [ y / n ]: ", message.data());
|
||||||
@@ -85,6 +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;
|
||||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.data(), "r"), pclose);
|
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.data(), "r"), pclose);
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
throw Error("Cannot run command: %s", cmd.data());
|
throw Error("Cannot run command: %s", cmd.data());
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ set(LIBPARTITION_MAP_SOURCES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/PartitionMap.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/PartitionMap.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Type.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/Type.cpp
|
||||||
)
|
)
|
||||||
set(LIBPARTITION_MAP_FLAGS -DLOG_FILE="/storage/emulated/0/.last_pmt.log" -DPROGRAM_NAME="libpartition_map")
|
|
||||||
|
|
||||||
# Add targets
|
# Add targets
|
||||||
add_library(partition_map_shared SHARED ${LIBPARTITION_MAP_SOURCES})
|
add_library(partition_map_shared SHARED ${LIBPARTITION_MAP_SOURCES})
|
||||||
@@ -31,10 +30,7 @@ add_executable(libpartition_map_test tests/test.cpp)
|
|||||||
set_target_properties(partition_map_shared PROPERTIES OUTPUT_NAME "partition_map")
|
set_target_properties(partition_map_shared PROPERTIES OUTPUT_NAME "partition_map")
|
||||||
set_target_properties(partition_map_static PROPERTIES OUTPUT_NAME "partition_map")
|
set_target_properties(partition_map_static PROPERTIES OUTPUT_NAME "partition_map")
|
||||||
|
|
||||||
# Set compiler flags
|
# Set linker flags
|
||||||
target_compile_options(partition_map_shared PRIVATE ${LIBPARTITION_MAP_FLAGS})
|
|
||||||
target_compile_options(partition_map_static PRIVATE ${LIBPARTITION_MAP_FLAGS})
|
|
||||||
target_compile_options(libpartition_map_test PRIVATE ${LIBPARTITION_MAP_FLAGS})
|
|
||||||
target_link_options(libpartition_map_test PRIVATE "LINKER:-rpath,/data/data/com.termux/files/usr/lib")
|
target_link_options(libpartition_map_test PRIVATE "LINKER:-rpath,/data/data/com.termux/files/usr/lib")
|
||||||
target_link_options(partition_map_shared PRIVATE "LINKER:-rpath,/data/data/com.termux/files/usr/lib")
|
target_link_options(partition_map_shared PRIVATE "LINKER:-rpath,/data/data/com.termux/files/usr/lib")
|
||||||
target_link_libraries(libpartition_map_test PRIVATE partition_map_shared PRIVATE helper_shared)
|
target_link_libraries(libpartition_map_test PRIVATE partition_map_shared PRIVATE helper_shared)
|
||||||
|
|||||||
@@ -325,4 +325,6 @@ using Map = basic_partition_map_builder;
|
|||||||
|
|
||||||
} // namespace PartitionMap
|
} // namespace PartitionMap
|
||||||
|
|
||||||
|
#define MAP "libpartition_map"
|
||||||
|
|
||||||
#endif // #ifndef LIBPARTITION_MAP_LIB_HPP
|
#endif // #ifndef LIBPARTITION_MAP_LIB_HPP
|
||||||
|
|||||||
@@ -55,12 +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;
|
||||||
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;
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +96,8 @@ 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;
|
||||||
|
|
||||||
for (const auto& path : defaultEntryList) {
|
for (const auto& path : defaultEntryList) {
|
||||||
if (std::filesystem::exists(path)) {
|
if (std::filesystem::exists(path)) {
|
||||||
_current_map = _build_map(path);
|
_current_map = _build_map(path);
|
||||||
@@ -110,12 +114,15 @@ 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.");
|
throw Error("Cannot build map by any default search entry.");
|
||||||
|
|
||||||
|
LOGN(MAP, INFO) << __func__ << "(): 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;
|
||||||
|
|
||||||
if (std::filesystem::exists(path)) {
|
if (std::filesystem::exists(path)) {
|
||||||
_is_real_block_dir(path);
|
_is_real_block_dir(path);
|
||||||
_current_map = _build_map(path);
|
_current_map = _build_map(path);
|
||||||
@@ -124,6 +131,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;
|
||||||
_insert_logicals(_build_map("/dev/block/mapper", true));
|
_insert_logicals(_build_map("/dev/block/mapper", true));
|
||||||
_map_builded = true;
|
_map_builded = true;
|
||||||
}
|
}
|
||||||
@@ -150,6 +158,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;
|
||||||
|
|
||||||
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;
|
||||||
@@ -161,6 +170,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;
|
||||||
_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;
|
||||||
|
|||||||
@@ -142,13 +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;
|
||||||
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;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@@ -203,6 +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;
|
||||||
delete[] _data;
|
delete[] _data;
|
||||||
_count = 0;
|
_count = 0;
|
||||||
_capacity = 6;
|
_capacity = 6;
|
||||||
|
|||||||
Reference in New Issue
Block a user