getpkg/dropshell-tool/src/ArchiveManager.cpp
2025-05-28 22:26:47 +12:00

71 lines
2.3 KiB
C++

#include <string>
#include <vector>
#include <fstream>
#include <filesystem>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <unistd.h>
#include "ArchiveManager.hpp"
namespace fs = std::filesystem;
ArchiveManager::ArchiveManager() {}
bool ArchiveManager::pack(const std::string& folderPath, const std::string& archivePath) {
// Use system tar to create gzipped tarball
std::ostringstream cmd;
cmd << "tar -czf '" << archivePath << "' -C '" << folderPath << "' .";
int ret = std::system(cmd.str().c_str());
return ret == 0;
}
bool ArchiveManager::unpack(const std::string& archivePath, const std::string& outDir) {
fs::create_directories(outDir);
std::ostringstream cmd;
cmd << "tar -xzf '" << archivePath << "' -C '" << outDir << "'";
int ret = std::system(cmd.str().c_str());
return ret == 0;
}
bool ArchiveManager::readConfigJson(const std::string& archivePath, std::string& outJson) {
// Extract config json to stdout
std::ostringstream cmd;
cmd << "tar -xOzf '" << archivePath << "' dropshell-tool-config.json";
FILE* pipe = popen(cmd.str().c_str(), "r");
if (!pipe) return false;
char buffer[4096];
std::ostringstream ss;
size_t n;
while ((n = fread(buffer, 1, sizeof(buffer), pipe)) > 0) {
ss.write(buffer, n);
}
int ret = pclose(pipe);
if (ret != 0) return false;
outJson = ss.str();
return true;
}
bool ArchiveManager::writeConfigJson(const std::string& archivePath, const std::string& json) {
// 1. Extract archive to temp dir
std::string tmpDir = "/tmp/dropshell_tool_tmp_" + std::to_string(::getpid());
fs::create_directories(tmpDir);
std::ostringstream extractCmd;
extractCmd << "tar -xzf '" << archivePath << "' -C '" << tmpDir << "'";
if (std::system(extractCmd.str().c_str()) != 0) return false;
// 2. Write new config json
std::ofstream ofs(tmpDir + "/dropshell-tool-config.json", std::ios::binary);
if (!ofs) return false;
ofs << json;
ofs.close();
// 3. Repack
std::ostringstream packCmd;
packCmd << "tar -czf '" << archivePath << "' -C '" << tmpDir << "' .";
int ret = std::system(packCmd.str().c_str());
// 4. Cleanup
std::ostringstream rmCmd;
rmCmd << "rm -rf '" << tmpDir << "'";
std::system(rmCmd.str().c_str());
return ret == 0;
}