pmt: improve libhelper, etc.

This commit is contained in:
2025-09-13 11:36:29 +03:00
parent b99f20c6a1
commit 398b119cb4
9 changed files with 96 additions and 72 deletions

View File

@@ -31,7 +31,7 @@
// Quick access to variables. // Quick access to variables.
#define VARS (*Variables) #define VARS (*Variables)
// Quick access to partition map. // Quick access to partition map.
#define PART_MAP (*(*Variables).PartMap) #define PART_MAP (*VARS.PartMap)
namespace PartitionManager { namespace PartitionManager {
enum basic_function_flags { enum basic_function_flags {
@@ -97,10 +97,6 @@ int Main(int argc, char **argv);
__attribute__((format(printf, 1, 2))) void print(const char *format, ...); __attribute__((format(printf, 1, 2))) void print(const char *format, ...);
__attribute__((format(printf, 1, 2))) void println(const char *format, ...); __attribute__((format(printf, 1, 2))) void println(const char *format, ...);
// Format it input and return as std::string
__attribute__((format(printf, 1, 2))) std::string format(const char *format,
...);
// If there is a delimiter in the string, CLI::detail::split returns; if not, an // If there is a delimiter in the string, CLI::detail::split returns; if not, an
// empty vector is returned. And checks duplicate arguments. // empty vector is returned. And checks duplicate arguments.
std::vector<std::string> splitIfHasDelim(const std::string &s, char delim, std::vector<std::string> splitIfHasDelim(const std::string &s, char delim,

View File

@@ -199,15 +199,6 @@ void println(const char *format, ...) {
va_end(args); va_end(args);
} }
std::string format(const char *format, ...) {
va_list args;
va_start(args, format);
char str[1024];
vsnprintf(str, sizeof(str), format, args);
va_end(args);
return str;
}
std::string getLibVersion() { MKVERSION(PMT); } std::string getLibVersion() { MKVERSION(PMT); }
std::string getAppVersion() { MKVERSION(PMTE); } std::string getAppVersion() { MKVERSION(PMTE); }

View File

@@ -31,7 +31,7 @@ namespace PartitionManager {
RUN_ASYNC(const std::string &partitionName, const std::string &outputName, RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
const uint64_t bufferSize) { const uint64_t bufferSize) {
if (!PART_MAP.hasPartition(partitionName)) if (!PART_MAP.hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {Helper::format("Couldn't find partition: %s", partitionName.data()), false};
LOGN(BFUN, INFO) << "Back upping " << partitionName << " as " << outputName LOGN(BFUN, INFO) << "Back upping " << partitionName << " as " << outputName
<< std::endl; << std::endl;
@@ -44,13 +44,13 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
<< std::endl; << std::endl;
else else
return { return {
format("Used --logical (-l) flag but is not logical partition: %s", Helper::format("Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
if (Helper::fileIsExists(outputName) && !VARS.forceProcess) if (Helper::fileIsExists(outputName) && !VARS.forceProcess)
return {format("%s is exists. Remove it, or use --force (-f) flag.", return {Helper::format("%s is exists. Remove it, or use --force (-f) flag.",
outputName.data()), outputName.data()),
false}; false};
@@ -63,14 +63,14 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
const int pfd = Helper::openAndAddToCloseList( const int pfd = Helper::openAndAddToCloseList(
PART_MAP.getRealPathOf(partitionName), collector, O_RDONLY); PART_MAP.getRealPathOf(partitionName), collector, O_RDONLY);
if (pfd < 0) if (pfd < 0)
return {format("Can't open partition: %s: %s", partitionName.data(), return {Helper::format("Can't open partition: %s: %s", partitionName.data(),
strerror(errno)), strerror(errno)),
false}; false};
const int ffd = Helper::openAndAddToCloseList( const int ffd = Helper::openAndAddToCloseList(
outputName, collector, O_WRONLY | O_CREAT | O_TRUNC, 0644); outputName, collector, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (ffd < 0) if (ffd < 0)
return {format("Can't create/open output file %s: %s", outputName.data(), return {Helper::format("Can't create/open output file %s: %s", outputName.data(),
strerror(errno)), strerror(errno)),
false}; false};
@@ -84,7 +84,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
while ((bytesRead = read(pfd, buffer, bufferSize)) > 0) { while ((bytesRead = read(pfd, buffer, bufferSize)) > 0) {
if (const ssize_t bytesWritten = write(ffd, buffer, bytesRead); if (const ssize_t bytesWritten = write(ffd, buffer, bytesRead);
bytesWritten != bytesRead) bytesWritten != bytesRead)
return {format("Can't write partition to output file %s: %s", return {Helper::format("Can't write partition to output file %s: %s",
outputName.data(), strerror(errno)), outputName.data(), strerror(errno)),
false}; false};
} }
@@ -100,7 +100,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
<< ". Access problems maybe occur in non-root mode" << ". Access problems maybe occur in non-root mode"
<< std::endl; << std::endl;
return {format("%s partition successfully back upped to %s", return {Helper::format("%s partition successfully back upped to %s",
partitionName.data(), outputName.data()), partitionName.data(), outputName.data()),
true}; true};
} }

View File

@@ -17,7 +17,6 @@ Copyright 2025 Yağız Zengin
#include "functions.hpp" #include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <cerrno> #include <cerrno>
#include <cstdlib>
#include <fcntl.h> #include <fcntl.h>
#include <future> #include <future>
#include <unistd.h> #include <unistd.h>
@@ -28,7 +27,7 @@ Copyright 2025 Yağız Zengin
namespace PartitionManager { namespace PartitionManager {
RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) { RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
if (!PART_MAP.hasPartition(partitionName)) if (!PART_MAP.hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {Helper::format("Couldn't find partition: %s", partitionName.data()), false};
if (VARS.onLogical && !PART_MAP.isLogical(partitionName)) { if (VARS.onLogical && !PART_MAP.isLogical(partitionName)) {
if (VARS.forceProcess) if (VARS.forceProcess)
@@ -38,7 +37,7 @@ RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
<< std::endl; << std::endl;
else else
return { return {
format("Used --logical (-l) flag but is not logical partition: %s", Helper::format("Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
@@ -51,15 +50,17 @@ RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
const int pfd = Helper::openAndAddToCloseList( const int pfd = Helper::openAndAddToCloseList(
PART_MAP.getRealPathOf(partitionName), collector, O_WRONLY); PART_MAP.getRealPathOf(partitionName), collector, O_WRONLY);
if (pfd < 0) if (pfd < 0)
return {format("Can't open partition: %s: %s", partitionName.data(), return {Helper::format("Can't open partition: %s: %s", partitionName.data(),
strerror(errno)), strerror(errno)),
false}; false};
if (!VARS.forceProcess) if (!VARS.forceProcess) {
Helper::confirmPropt( if (!Helper::confirmPropt(
"Are you sure you want to continue? This could render your device " "Are you sure you want to continue? This could render your device "
"unusable! Do not continue if you " "unusable! Do not continue if you "
"do not know what you are doing!"); "do not know what you are doing!"))
throw Error("Operation canceled.");
}
LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName
<< std::endl; << std::endl;
@@ -76,13 +77,13 @@ RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
toWrite = partitionSize - bytesWritten; toWrite = partitionSize - bytesWritten;
if (const ssize_t result = write(pfd, buffer, toWrite); result == -1) if (const ssize_t result = write(pfd, buffer, toWrite); result == -1)
return {format("Can't write zero bytes to partition: %s: %s", return {Helper::format("Can't write zero bytes to partition: %s: %s",
partitionName.data(), strerror(errno)), partitionName.data(), strerror(errno)),
false}; false};
else bytesWritten += result; else bytesWritten += result;
} }
return {format("Successfully wrote zero bytes to the %s partition\n", return {Helper::format("Successfully wrote zero bytes to the %s partition",
partitionName.data()), partitionName.data()),
true}; true};
} }

View File

@@ -29,11 +29,11 @@ namespace PartitionManager {
RUN_ASYNC(const std::string &partitionName, const std::string &imageName, RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
const uint64_t bufferSize, const bool deleteAfterProgress) { const uint64_t bufferSize, const bool deleteAfterProgress) {
if (!Helper::fileIsExists(imageName)) if (!Helper::fileIsExists(imageName))
return {format("Couldn't find image file: %s", imageName.data()), false}; return {Helper::format("Couldn't find image file: %s", imageName.data()), false};
if (!PART_MAP.hasPartition(partitionName)) if (!PART_MAP.hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {Helper::format("Couldn't find partition: %s", partitionName.data()), false};
if (Helper::fileSize(imageName) > PART_MAP.sizeOf(partitionName)) if (Helper::fileSize(imageName) > PART_MAP.sizeOf(partitionName))
return {format("%s is larger than %s partition size!", imageName.data(), return {Helper::format("%s is larger than %s partition size!", imageName.data(),
partitionName.data()), partitionName.data()),
false}; false};
@@ -48,7 +48,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
<< std::endl; << std::endl;
else else
return { return {
format("Used --logical (-l) flag but is not logical partition: %s", Helper::format("Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
@@ -60,14 +60,14 @@ RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
const int ffd = Helper::openAndAddToCloseList(imageName, collector, O_RDONLY); const int ffd = Helper::openAndAddToCloseList(imageName, collector, O_RDONLY);
if (ffd < 0) if (ffd < 0)
return {format("Can't open image file %s: %s", imageName.data(), return {Helper::format("Can't open image file %s: %s", imageName.data(),
strerror(errno)), strerror(errno)),
false}; false};
const int pfd = Helper::openAndAddToCloseList( const int pfd = Helper::openAndAddToCloseList(
PART_MAP.getRealPathOf(partitionName), collector, O_RDWR | O_TRUNC); PART_MAP.getRealPathOf(partitionName), collector, O_RDWR | O_TRUNC);
if (pfd < 0) if (pfd < 0)
return {format("Can't open partition: %s: %s", partitionName.data(), return {Helper::format("Can't open partition: %s: %s", partitionName.data(),
strerror(errno)), strerror(errno)),
false}; false};
@@ -81,7 +81,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
while ((bytesRead = read(ffd, buffer, bufferSize)) > 0) { while ((bytesRead = read(ffd, buffer, bufferSize)) > 0) {
if (const ssize_t bytesWritten = write(pfd, buffer, bytesRead); if (const ssize_t bytesWritten = write(pfd, buffer, bytesRead);
bytesWritten != bytesRead) bytesWritten != bytesRead)
return {format("Can't write partition to output file %s: %s", return {Helper::format("Can't write partition to output file %s: %s",
imageName.data(), strerror(errno)), imageName.data(), strerror(errno)),
false}; false};
} }
@@ -93,7 +93,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
std::string("Cannot erase flash file: " + imageName + "\n").data()); std::string("Cannot erase flash file: " + imageName + "\n").data());
} }
return {format("%s is successfully wrote to %s partition", imageName.data(), return {Helper::format("%s is successfully wrote to %s partition", imageName.data(),
partitionName.data()), partitionName.data()),
true}; true};
} }

View File

@@ -66,11 +66,11 @@ INIT {
RUN { RUN {
std::vector<PartitionMap::Partition_t> jParts; std::vector<PartitionMap::Partition_t> jParts;
std::string multiple; sizeCastTypes multiple;
if (asByte) multiple = "B"; if (asByte) multiple = B;
if (asKiloBytes) multiple = "KB"; if (asKiloBytes) multiple = KB;
if (asMega) multiple = "MB"; if (asMega) multiple = MB;
if (asGiga) multiple = "GB"; if (asGiga) multiple = GB;
auto func = [this, &jParts, &multiple] COMMON_LAMBDA_PARAMS -> bool { auto func = [this, &jParts, &multiple] COMMON_LAMBDA_PARAMS -> bool {
if (VARS.onLogical && !props.isLogical) { if (VARS.onLogical && !props.isLogical) {
@@ -86,11 +86,11 @@ RUN {
if (jsonFormat) if (jsonFormat)
jParts.push_back({partition, jParts.push_back({partition,
{std::stoull(Helper::convertTo(props.size, multiple)), {static_cast<uint64_t>(Helper::convertTo(props.size, multiple)),
props.isLogical}}); props.isLogical}});
else else
println("partition=%s size=%s isLogical=%s", partition.data(), println("partition=%s size=%d isLogical=%s", partition.data(),
Helper::convertTo(props.size, multiple).data(), Helper::convertTo(props.size, multiple),
props.isLogical ? "true" : "false"); props.isLogical ? "true" : "false");
return true; return true;
@@ -106,7 +106,7 @@ RUN {
if (jsonFormat) { if (jsonFormat) {
nlohmann::json j; nlohmann::json j;
j["multipleType"] = multiple; j["multipleType"] = Helper::multipleToString(multiple);
j["partitions"] = nlohmann::json::array(); j["partitions"] = nlohmann::json::array();
for (const auto &[name, props] : jParts) { for (const auto &[name, props] : jParts) {
j["partitions"].push_back({{jNamePartition, name}, j["partitions"].push_back({{jNamePartition, name},

View File

@@ -42,7 +42,7 @@ INIT {
->default_val(false); ->default_val(false);
cmd->add_flag("--as-megabyte", asMega, cmd->add_flag("--as-megabyte", asMega,
"Tell input size of partition list as megabyte.") "Tell input size of partition list as megabyte.")
->default_val(false); ->default_val(true);
cmd->add_flag("--as-gigabyte", asGiga, cmd->add_flag("--as-gigabyte", asGiga,
"Tell input size of partition list as gigabyte.") "Tell input size of partition list as gigabyte.")
->default_val(false); ->default_val(false);
@@ -54,7 +54,13 @@ INIT {
} }
RUN { RUN {
auto func = [this] COMMON_LAMBDA_PARAMS -> bool { sizeCastTypes multiple = {};
if (asByte) multiple = B;
if (asKiloBytes) multiple = KB;
if (asMega) multiple = MB;
if (asGiga) multiple = GB;
auto func = [this, &multiple] COMMON_LAMBDA_PARAMS -> bool {
if (VARS.onLogical && !props.isLogical) { if (VARS.onLogical && !props.isLogical) {
if (VARS.forceProcess) if (VARS.forceProcess)
LOGN(SFUN, WARNING) LOGN(SFUN, WARNING)
@@ -66,16 +72,10 @@ RUN {
partition.data()); partition.data());
} }
std::string multiple = "MB"; if (onlySize) println("%d", Helper::convertTo(props.size, multiple));
if (asByte) multiple = "B";
if (asKiloBytes) multiple = "KB";
if (asMega) multiple = "MB";
if (asGiga) multiple = "GB";
if (onlySize) println("%s", Helper::convertTo(props.size, multiple).data());
else else
println("%s: %s%s", partition.data(), println("%s: %d%s", partition.data(),
Helper::convertTo(props.size, multiple).data(), multiple.data()); Helper::convertTo(props.size, multiple), Helper::multipleToString(multiple).data());
return true; return true;
}; };

View File

@@ -44,6 +44,13 @@ enum LogLevels {
ABORT = static_cast<int>('A') ABORT = static_cast<int>('A')
}; };
enum sizeCastTypes {
B = static_cast<int>('B'),
KB = static_cast<int>('K'),
MB = static_cast<int>('M'),
GB = static_cast<int>('G')
};
constexpr mode_t DEFAULT_FILE_PERMS = 0644; constexpr mode_t DEFAULT_FILE_PERMS = 0644;
constexpr mode_t DEFAULT_EXTENDED_FILE_PERMS = 0755; constexpr mode_t DEFAULT_EXTENDED_FILE_PERMS = 0755;
constexpr mode_t DEFAULT_DIR_PERMS = 0755; constexpr mode_t DEFAULT_DIR_PERMS = 0755;
@@ -342,18 +349,29 @@ std::string pathDirname(std::string_view entry);
uint64_t getRandomOffset(uint64_t size, uint64_t bufferSize); uint64_t getRandomOffset(uint64_t size, uint64_t bufferSize);
/** /**
* Convert input size to input multiple * Convert input size to input multiple.
*/ */
std::string convertTo(uint64_t size, const std::string &multiple); int convertTo(uint64_t size, sizeCastTypes type);
/**
* Convert input multiple variable to string.
*/
std::string multipleToString(sizeCastTypes type);
/**
* Format it input and return as std::string.
*/
__attribute__((format(printf, 1, 2))) std::string format(const char *format,
...);
/** /**
* Convert input size to input multiple * Convert input size to input multiple
*/ */
template <uint64_t size> std::string convertTo(const std::string &multiple) { template <uint64_t size> int convertTo(const sizeCastTypes type) {
if (multiple == "KB") return std::to_string(TO_KB(size)); if (type == KB) return TO_KB(size);
if (multiple == "MB") return std::to_string(TO_MB(size)); if (type == MB) return TO_MB(size);
if (multiple == "GB") return std::to_string(TO_GB(size)); if (type == GB) return TO_GB(size);
return std::to_string(size); return static_cast<int>(size);
} }
// ------------------------------- // -------------------------------
@@ -361,12 +379,12 @@ template <uint64_t size> std::string convertTo(const std::string &multiple) {
// ------------------------------- // -------------------------------
#ifdef __ANDROID__ #ifdef __ANDROID__
/** /**
* Get input property as string. * Get input property as string (for Android).
*/ */
std::string getProperty(std::string_view prop); std::string getProperty(std::string_view prop);
/** /**
* Reboot device to input mode. * Reboot device to input mode (for Android).
*/ */
bool reboot(std::string_view arg); bool reboot(std::string_view arg);
#endif #endif

View File

@@ -35,6 +35,7 @@
#include <sys/_system_properties.h> #include <sys/_system_properties.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <cstdarg>
#ifdef __ANDROID__ #ifdef __ANDROID__
// From system/core/libcutils/android_reboot.cpp android16-s2-release // From system/core/libcutils/android_reboot.cpp android16-s2-release
@@ -228,14 +229,31 @@ bool reboot(const std::string_view arg) {
uint64_t getRandomOffset(const uint64_t size, const uint64_t bufferSize) { uint64_t getRandomOffset(const uint64_t size, const uint64_t bufferSize) {
if (size <= bufferSize) return 0; if (size <= bufferSize) return 0;
const uint64_t maxOffset = size - bufferSize; const uint64_t maxOffset = size - bufferSize;
srand(time(nullptr));
return rand() % maxOffset; return rand() % maxOffset;
} }
std::string convertTo(const uint64_t size, const std::string &multiple) { int convertTo(const uint64_t size, const sizeCastTypes type) {
if (multiple == "KB") return std::to_string(TO_KB(size)); if (type == KB) return TO_KB(size);
if (multiple == "MB") return std::to_string(TO_MB(size)); if (type == MB) return TO_MB(size);
if (multiple == "GB") return std::to_string(TO_GB(size)); if (type == GB) return TO_GB(size);
return std::to_string(size); return static_cast<int>(size);
}
std::string multipleToString(const sizeCastTypes type) {
if (type == KB) return "KB";
if (type == MB) return "MB";
if (type == GB) return "GB";
return "B";
}
std::string format(const char *format, ...) {
va_list args;
va_start(args, format);
char str[1024];
vsnprintf(str, sizeof(str), format, args);
va_end(args);
return str;
} }
std::string getLibVersion() { MKVERSION("libhelper"); } std::string getLibVersion() { MKVERSION("libhelper"); }