Your Name 95da0d28d4
Some checks failed
Build-Test-Publish / build (linux/arm64) (push) Failing after 9s
Build-Test-Publish / build (linux/amd64) (push) Successful in 26s
Build-Test-Publish / test-install-from-scratch (linux/amd64) (push) Has been skipped
Build-Test-Publish / test-install-from-scratch (linux/arm64) (push) Has been skipped
Modify dehydrate/test.sh
2025-06-25 17:54:30 +12:00

115 lines
4.0 KiB
C++

#include <fstream>
#include <filesystem>
#include <string>
#include <iostream>
#include <cstring>
// Tiny dependency-free FNV-1a 64-bit hash
static uint64_t fnv1a_64(const void* data, size_t len) {
const uint8_t* p = static_cast<const uint8_t*>(data);
uint64_t h = 0xcbf29ce484222325ULL;
for (size_t i = 0; i < len; ++i)
h = (h ^ p[i]) * 0x100000001b3ULL;
return h;
}
#include "_test1.hpp"
namespace recreate_test1 {
// Base64 decoding function - no dependencies
static void base64_decode(const char* encoded_data, size_t encoded_len, unsigned char* output, size_t* output_len) {
const char* base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
size_t out_pos = 0;
int val = 0, valb = -8;
for (size_t i = 0; i < encoded_len; i++) {
char c = encoded_data[i];
if (c == '=') break;
// Find position in base64_chars
const char* pos = strchr(base64_chars, c);
if (pos == nullptr) continue; // Skip invalid characters
val = (val << 6) + static_cast<int>(pos - base64_chars);
valb += 6;
if (valb >= 0) {
output[out_pos++] = static_cast<unsigned char>((val >> valb) & 0xFF);
valb -= 8;
}
}
*output_len = out_pos;
}
// Utility function to recreate a file with proper permissions
static bool _recreate_file_(const std::filesystem::path& outpath, uint64_t file_hash, std::filesystem::perms file_perms, const unsigned char* filedata, size_t filedata_len) {
namespace fs = std::filesystem;
bool needs_write = false;
// Check if file exists and has correct hash
if (fs::exists(outpath)) {
// Check content hash
std::ifstream in(outpath, std::ios::binary);
std::ostringstream oss;
oss << in.rdbuf();
std::string data = oss.str();
uint64_t existing_hash = fnv1a_64(data.data(), data.size());
needs_write = existing_hash != file_hash;
} else {
needs_write = true; // File doesn't exist, need to create it
}
bool needs_permission_update = true;
if (!needs_write) { // we always update permissions if the file is written or changed. Othewise we check.
fs::perms current_perms = fs::status(outpath).permissions();
needs_permission_update = current_perms != file_perms;
}
if (needs_write) {
bool existed = fs::exists(outpath);
fs::create_directories(outpath.parent_path());
std::ofstream out(outpath, std::ios::binary);
out.write(reinterpret_cast<const char*>(filedata), filedata_len);
out.close();
// Set the file permissions
fs::permissions(outpath, file_perms);
if (!existed) {
std::cout << "[dehydrate] " << outpath.filename() << ": created\n";
} else {
std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n";
}
return true;
}
if (needs_permission_update) {
// Update only permissions
fs::permissions(outpath, file_perms);
std::cout << "[dehydrate] " << outpath.filename() << ": updated (permissions changed)\n";
return true;
}
return false;
}
bool recreate_file(std::string destination_folder) {
namespace fs = std::filesystem;
fs::path outpath = fs::path(destination_folder) / "test1.txt";
// File data embedded as Base64
static const char filedata_base64[] = "VGhpcyBpcyBhIHNpbXBsZSB0ZXh0IGZpbGUuCkl0IGhhcyBtdWx0aXBsZSBsaW5lcy4KTGluZSAz"\
"Lg==";
// Decode Base64 data
size_t decoded_size = (strlen(filedata_base64) * 3) / 4;
unsigned char* decoded_data = new unsigned char[decoded_size];
size_t actual_size;
base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size);
bool result = _recreate_file_(outpath, 11900461415522640014ULL, std::filesystem::perms(384), decoded_data, actual_size);
delete[] decoded_data;
return result;
}
}