feat: Update 5 files
Some checks failed
Build-Test-Publish / build (linux/arm64) (push) Failing after 9s
Build-Test-Publish / build (linux/amd64) (push) Failing after 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
Some checks failed
Build-Test-Publish / build (linux/arm64) (push) Failing after 9s
Build-Test-Publish / build (linux/amd64) (push) Failing after 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
This commit is contained in:
42
bb64/src/b64ed.cpp
Normal file
42
bb64/src/b64ed.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "b64ed.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// Custom base64 encoding/decoding tables
|
||||
static const std::string custom_base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+_";
|
||||
|
||||
std::string base64_encode(const std::string &in) {
|
||||
std::string out;
|
||||
int val = 0, valb = -6;
|
||||
for (unsigned char c : in) {
|
||||
val = (val << 8) + c;
|
||||
valb += 8;
|
||||
while (valb >= 0) {
|
||||
out.push_back(custom_base64_chars[(val >> valb) & 0x3F]);
|
||||
valb -= 6;
|
||||
}
|
||||
}
|
||||
if (valb > -6) out.push_back(custom_base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
|
||||
while (out.size() % 4) out.push_back('=');
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string base64_decode(const std::string &in) {
|
||||
std::vector<int> T(256, -1);
|
||||
for (int i = 0; i < 64; i++) T[custom_base64_chars[i]] = i;
|
||||
std::string out;
|
||||
int val = 0, valb = -8;
|
||||
for (unsigned char c : in) {
|
||||
if (T[c] == -1) break;
|
||||
val = (val << 6) + T[c];
|
||||
valb += 6;
|
||||
if (valb >= 0) {
|
||||
out.push_back(char((val >> valb) & 0xFF));
|
||||
valb -= 8;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
9
bb64/src/b64ed.hpp
Normal file
9
bb64/src/b64ed.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef B64ED_HPP
|
||||
#define B64ED_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string base64_decode(const std::string &in);
|
||||
std::string base64_encode(const std::string &in);
|
||||
|
||||
#endif
|
207
bb64/src/bb64.cpp
Normal file
207
bb64/src/bb64.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include "version.h"
|
||||
#include "b64ed.hpp"
|
||||
|
||||
// Recursively decode and print if nested bb64 command is found
|
||||
void recursive_print(const std::string &decoded)
|
||||
{
|
||||
std::cout << std::string(80, '-') << std::endl;
|
||||
std::cout << decoded << std::endl;
|
||||
std::cout << std::string(80, '-') << std::endl;
|
||||
|
||||
size_t pos = decoded.find("bb64 ");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::istringstream iss(decoded.substr(pos));
|
||||
std::string cmd, arg;
|
||||
iss >> cmd >> arg;
|
||||
if (cmd == "bb64" && !arg.empty())
|
||||
{
|
||||
std::string nested = base64_decode(arg);
|
||||
std::cout << " ";
|
||||
std::cout << "nested: " << nested << std::endl;
|
||||
recursive_print(nested);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constexpr unsigned int hash(const char *s, int off = 0)
|
||||
{
|
||||
return !s[off] ? 5381 : (hash(s, off + 1) * 33) ^ s[off];
|
||||
}
|
||||
|
||||
std::string tidy(const std::string &str)
|
||||
{
|
||||
std::string result;
|
||||
bool in_whitespace = false;
|
||||
for (char c : str)
|
||||
{
|
||||
// Remove non-printable characters except for whitespace (space, tab, newline, carriage return)
|
||||
if ((static_cast<unsigned char>(c) < 32 && c != ' ' && c != '\t' && c != '\n' && c != '\r') || static_cast<unsigned char>(c) == 127)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
{
|
||||
if (!in_whitespace)
|
||||
{
|
||||
result += ' ';
|
||||
in_whitespace = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result += c;
|
||||
in_whitespace = false;
|
||||
}
|
||||
}
|
||||
// Remove leading whitespace
|
||||
size_t start = result.find_first_not_of(' ');
|
||||
if (start == std::string::npos)
|
||||
return "";
|
||||
// Remove trailing whitespace
|
||||
size_t end = result.find_last_not_of(' ');
|
||||
return result.substr(start, end - start + 1);
|
||||
}
|
||||
|
||||
|
||||
std::string get_arch()
|
||||
{
|
||||
// determine the architecture of the system
|
||||
std::string arch;
|
||||
#ifdef __aarch64__
|
||||
arch = "arm64";
|
||||
#elif __x86_64__
|
||||
arch = "amd64";
|
||||
#endif
|
||||
return arch;
|
||||
}
|
||||
|
||||
int update_bb64()
|
||||
{
|
||||
// determine path to this executable
|
||||
std::filesystem::path bb64_path = std::filesystem::canonical("/proc/self/exe");
|
||||
std::filesystem::path parent_path = bb64_path.parent_path();
|
||||
|
||||
// determine the architecture of the system
|
||||
std::string arch = get_arch();
|
||||
|
||||
std::string url = "https://gitea.jde.nz/public/bb64/releases/download/latest/bb64." + arch;
|
||||
|
||||
// download new version, preserve permissions and ownership
|
||||
std::string bash_script;
|
||||
bash_script += "docker run --rm -v "+parent_path.string()+":/target";
|
||||
bash_script += " gitea.jde.nz/public/debian-curl:latest";
|
||||
bash_script += " sh -c \"";
|
||||
bash_script += " curl -fsSL " + url + " -o /target/bb64_temp &&";
|
||||
bash_script += " chmod --reference=/target/bb64 /target/bb64_temp &&";
|
||||
bash_script += " chown --reference=/target/bb64 /target/bb64_temp &&";
|
||||
bash_script += " mv /target/bb64_temp /target/bb64";
|
||||
bash_script += "\"";
|
||||
|
||||
std::cout << "Updating " << bb64_path << " to the latest " << arch << " version." << std::endl;
|
||||
|
||||
// std::cout << "bash_script: " << std::endl
|
||||
// << bash_script << std::endl;
|
||||
|
||||
// run the bash script
|
||||
execlp("bash", "bash", "-c", bash_script.c_str(), (char *)nullptr);
|
||||
std::cerr << "Failed to execute command." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int decode_and_run(const std::string &encoded)
|
||||
{
|
||||
// Default: decode and run
|
||||
std::string decoded = base64_decode(encoded);
|
||||
if (decoded.empty())
|
||||
{
|
||||
std::cerr << "Failed to decode base64 command." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Replace current process with bash -c "decoded"
|
||||
execlp("bash", "bash", "-c", decoded.c_str(), (char *)nullptr);
|
||||
// If execlp returns, there was an error
|
||||
std::cerr << "Failed to execute command." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cerr << "bb64 version " << VERSION << ", by J842." << std::endl;
|
||||
// heredoc for instructions
|
||||
std::cerr << R"(
|
||||
|
||||
Usage:
|
||||
bb64 BASE64COMMAND Decodes and runs the command
|
||||
bb64 -[i|d] BASE64COMMAND Displays the decoded command
|
||||
|
||||
bb64 -e COMMAND Encodes the command and prints the base64 encoded result
|
||||
bb64 -e Encodes the command provided on stdin and prints the result
|
||||
|
||||
bb64 -u Updates bb64 to the latest version (uses docker)
|
||||
|
||||
bb64 -v Prints the version number
|
||||
|
||||
)" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string mode = argv[1];
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
if (mode == "-u")
|
||||
return update_bb64();
|
||||
else if (mode == "-v")
|
||||
{
|
||||
std::cout << VERSION << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else if (mode == "-e")
|
||||
{
|
||||
std::ostringstream oss;
|
||||
while (std::cin)
|
||||
{
|
||||
std::string line;
|
||||
std::getline(std::cin, line);
|
||||
oss << line << std::endl;
|
||||
}
|
||||
std::string tidier = tidy(oss.str());
|
||||
std::cout << base64_encode(tidier) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return decode_and_run(mode);
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
std::string tidier;
|
||||
|
||||
switch (hash(mode.c_str()))
|
||||
{
|
||||
case hash("-i"):
|
||||
case hash("-d"):
|
||||
std::cout << "Decoding command..." << std::endl
|
||||
<< std::endl;
|
||||
recursive_print(base64_decode(argv[2]));
|
||||
break;
|
||||
case hash("-e"):
|
||||
for (int i = 2; i < argc; ++i)
|
||||
oss << (i > 2 ? " " : "") << argv[i];
|
||||
tidier = tidy(oss.str());
|
||||
std::cout << base64_encode(tidier) << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Invalid mode: " << mode << std::endl;
|
||||
return -1;
|
||||
};
|
||||
}
|
1
bb64/src/version.h
Normal file
1
bb64/src/version.h
Normal file
@ -0,0 +1 @@
|
||||
static const char *VERSION = "39";
|
Reference in New Issue
Block a user