pmt: add stdin parsing support, etc.

This commit is contained in:
2025-09-15 00:01:52 +03:00
parent 398b119cb4
commit 318739adc8
7 changed files with 67 additions and 44 deletions

View File

@@ -28,7 +28,11 @@
namespace PartitionManager { namespace PartitionManager {
// Usage: REGISTER_FUNCTION(FUNCTION_CLASS); /**
* Register functions. Uses ready 'FuncManager' variable.
*
* Usage: REGISTER_FUNCTION(FUNCTION_CLASS);
*/
#define REGISTER_FUNCTION(cls) \ #define REGISTER_FUNCTION(cls) \
FuncManager.registerFunction(std::make_unique<cls>(), AppMain) FuncManager.registerFunction(std::make_unique<cls>(), AppMain)
@@ -78,6 +82,22 @@ int Main(int argc, char **argv) {
collector.closeAfterProgress(pstdout); collector.closeAfterProgress(pstdout);
collector.closeAfterProgress(pstderr); collector.closeAfterProgress(pstderr);
signal(SIGINT, sigHandler);
signal(SIGABRT, sigHandler);
if (!isatty(fileno(stdin))) {
char buf[128];
while (fgets(buf, sizeof(buf), stdin) != nullptr) {
buf[strcspn(buf, "\n")] = 0;
const char *token = strtok(buf, " \t");
while (token != nullptr) {
argv[argc] = strdup(token);
argc++;
token = strtok(nullptr, " \t");
}
}
}
if (argc < 2) { if (argc < 2) {
println( println(
"Usage: %s [OPTIONS] [SUBCOMMAND]\nUse --help for more information.", "Usage: %s [OPTIONS] [SUBCOMMAND]\nUse --help for more information.",
@@ -85,9 +105,6 @@ int Main(int argc, char **argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
signal(SIGINT, sigHandler);
signal(SIGABRT, sigHandler);
CLI::App AppMain{"Partition Manager Tool"}; CLI::App AppMain{"Partition Manager Tool"};
FunctionManager FuncManager; FunctionManager FuncManager;

View File

@@ -31,7 +31,8 @@ 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 {Helper::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;
@@ -43,15 +44,15 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
<< std::endl; << std::endl;
else else
return { return {Helper::format(
Helper::format("Used --logical (-l) flag but is not logical partition: %s", "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 {Helper::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};
LOGN(BFUN, INFO) << "Using buffer size (for back upping " << partitionName LOGN(BFUN, INFO) << "Using buffer size (for back upping " << partitionName
@@ -64,14 +65,14 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
PART_MAP.getRealPathOf(partitionName), collector, O_RDONLY); PART_MAP.getRealPathOf(partitionName), collector, O_RDONLY);
if (pfd < 0) if (pfd < 0)
return {Helper::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 {Helper::format("Can't create/open output file %s: %s", outputName.data(), return {Helper::format("Can't create/open output file %s: %s",
strerror(errno)), outputName.data(), strerror(errno)),
false}; false};
LOGN(BFUN, INFO) << "Writing partition " << partitionName LOGN(BFUN, INFO) << "Writing partition " << partitionName
@@ -85,7 +86,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
if (const ssize_t bytesWritten = write(ffd, buffer, bytesRead); if (const ssize_t bytesWritten = write(ffd, buffer, bytesRead);
bytesWritten != bytesRead) bytesWritten != bytesRead)
return {Helper::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};
} }
@@ -101,7 +102,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &outputName,
<< std::endl; << std::endl;
return {Helper::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

@@ -27,7 +27,8 @@ 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 {Helper::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)
@@ -36,10 +37,10 @@ RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
<< std::endl; << std::endl;
else else
return { return {Helper::format(
Helper::format("Used --logical (-l) flag but is not logical partition: %s", "Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
LOGN(EFUN, INFO) << "Using buffer size: " << bufferSize; LOGN(EFUN, INFO) << "Using buffer size: " << bufferSize;
@@ -51,14 +52,14 @@ RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
PART_MAP.getRealPathOf(partitionName), collector, O_WRONLY); PART_MAP.getRealPathOf(partitionName), collector, O_WRONLY);
if (pfd < 0) if (pfd < 0)
return {Helper::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) {
if (!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."); throw Error("Operation canceled.");
} }
@@ -78,13 +79,13 @@ RUN_ASYNC(const std::string &partitionName, const uint64_t bufferSize) {
if (const ssize_t result = write(pfd, buffer, toWrite); result == -1) if (const ssize_t result = write(pfd, buffer, toWrite); result == -1)
return {Helper::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 {Helper::format("Successfully wrote zero bytes to the %s partition", return {Helper::format("Successfully wrote zero bytes to the %s partition",
partitionName.data()), partitionName.data()),
true}; true};
} }

View File

@@ -29,12 +29,14 @@ 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 {Helper::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 {Helper::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 {Helper::format("%s is larger than %s partition size!", imageName.data(), return {Helper::format("%s is larger than %s partition size!",
partitionName.data()), imageName.data(), partitionName.data()),
false}; false};
LOGN(FFUN, INFO) << "flashing " << imageName << " to " << partitionName LOGN(FFUN, INFO) << "flashing " << imageName << " to " << partitionName
@@ -47,10 +49,10 @@ RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
<< " is exists but not logical. Ignoring (from --force, -f)." << " is exists but not logical. Ignoring (from --force, -f)."
<< std::endl; << std::endl;
else else
return { return {Helper::format(
Helper::format("Used --logical (-l) flag but is not logical partition: %s", "Used --logical (-l) flag but is not logical partition: %s",
partitionName.data()), partitionName.data()),
false}; false};
} }
LOGN(FFUN, INFO) << "Using buffer size: " << bufferSize << std::endl; LOGN(FFUN, INFO) << "Using buffer size: " << bufferSize << std::endl;
@@ -61,14 +63,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 {Helper::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 {Helper::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};
LOGN(FFUN, INFO) << "Writing image " << imageName LOGN(FFUN, INFO) << "Writing image " << imageName
@@ -82,7 +84,7 @@ RUN_ASYNC(const std::string &partitionName, const std::string &imageName,
if (const ssize_t bytesWritten = write(pfd, buffer, bytesRead); if (const ssize_t bytesWritten = write(pfd, buffer, bytesRead);
bytesWritten != bytesRead) bytesWritten != bytesRead)
return {Helper::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,8 +95,8 @@ 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 {Helper::format("%s is successfully wrote to %s partition", imageName.data(), return {Helper::format("%s is successfully wrote to %s partition",
partitionName.data()), imageName.data(), partitionName.data()),
true}; true};
} }

View File

@@ -85,9 +85,10 @@ RUN {
} }
if (jsonFormat) if (jsonFormat)
jParts.push_back({partition, jParts.push_back(
{static_cast<uint64_t>(Helper::convertTo(props.size, multiple)), {partition,
props.isLogical}}); {static_cast<uint64_t>(Helper::convertTo(props.size, multiple)),
props.isLogical}});
else else
println("partition=%s size=%d isLogical=%s", partition.data(), println("partition=%s size=%d isLogical=%s", partition.data(),
Helper::convertTo(props.size, multiple), Helper::convertTo(props.size, multiple),

View File

@@ -75,7 +75,8 @@ RUN {
if (onlySize) println("%d", Helper::convertTo(props.size, multiple)); if (onlySize) println("%d", Helper::convertTo(props.size, multiple));
else else
println("%s: %d%s", partition.data(), println("%s: %d%s", partition.data(),
Helper::convertTo(props.size, multiple), Helper::multipleToString(multiple).data()); Helper::convertTo(props.size, multiple),
Helper::multipleToString(multiple).data());
return true; return true;
}; };

View File

@@ -25,6 +25,7 @@
#else #else
#include <sys/system_properties.h> #include <sys/system_properties.h>
#endif #endif
#include <cstdarg>
#include <cutils/android_reboot.h> #include <cutils/android_reboot.h>
#include <iostream> #include <iostream>
#include <libgen.h> #include <libgen.h>
@@ -35,7 +36,6 @@
#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