Implemented wirekit installation
This commit is contained in:
parent
6cd966c6a9
commit
528eccc626
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
enum class LAUNCH_MODE { HELP, INSTALL, UNINSTALL, LIST, RUN };
|
enum class LAUNCH_MODE { HELP, INSTALL, UNINSTALL, LIST, RUN };
|
||||||
|
|
||||||
LAUNCH_MODE launch_mode(const char* str);
|
LAUNCH_MODE launch_mode(const char* str);
|
||||||
|
bool home_directory(std::string& str);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
class DL {
|
class DL {
|
||||||
void* m_handle;
|
void* m_handle;
|
||||||
@ -8,7 +9,7 @@ public:
|
|||||||
DL& operator=(const DL& other) = delete;
|
DL& operator=(const DL& other) = delete;
|
||||||
DL& operator=(DL&& other) noexcept;
|
DL& operator=(DL&& other) noexcept;
|
||||||
|
|
||||||
DL(const char* path);
|
DL(const std::filesystem::path& dl);
|
||||||
~DL();
|
~DL();
|
||||||
|
|
||||||
void* resolve(const char* symbol) const;
|
void* resolve(const char* symbol) const;
|
||||||
|
|||||||
27
include/install.hpp
Normal file
27
include/install.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class InstallManager {
|
||||||
|
static constexpr const char* INSTALL_PATH = ".rewire/wirekits"; // Relative to home directory
|
||||||
|
|
||||||
|
bool m_valid;
|
||||||
|
std::filesystem::path m_home_directory;
|
||||||
|
std::filesystem::path m_install_directory;
|
||||||
|
public:
|
||||||
|
InstallManager(const InstallManager& other) = delete;
|
||||||
|
InstallManager(InstallManager&& other) noexcept;
|
||||||
|
InstallManager& operator=(const InstallManager& other) = delete;
|
||||||
|
InstallManager& operator=(InstallManager&& other) noexcept;
|
||||||
|
|
||||||
|
InstallManager();
|
||||||
|
~InstallManager();
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
|
bool install(const char* from, const char* to);
|
||||||
|
bool uninstall(const char* name);
|
||||||
|
bool get(const char* name, std::filesystem::path& path) const;
|
||||||
|
std::list<std::string> installs() const;
|
||||||
|
};
|
||||||
10
src/cli.cpp
10
src/cli.cpp
@ -1,6 +1,7 @@
|
|||||||
#include "cli.hpp"
|
#include "cli.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
LAUNCH_MODE launch_mode(const char* str) {
|
LAUNCH_MODE launch_mode(const char* str) {
|
||||||
if (std::strcmp(str, "help") == 0)
|
if (std::strcmp(str, "help") == 0)
|
||||||
@ -14,3 +15,12 @@ LAUNCH_MODE launch_mode(const char* str) {
|
|||||||
else
|
else
|
||||||
return LAUNCH_MODE::RUN;
|
return LAUNCH_MODE::RUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool home_directory(std::string& str) {
|
||||||
|
const char* hd_cstr = std::getenv("HOME");
|
||||||
|
if (!hd_cstr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = std::string{ hd_cstr };
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
13
src/dl.cpp
13
src/dl.cpp
@ -17,17 +17,8 @@ DL& DL::operator=(DL&& other) noexcept {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DL::DL(const char* path) : m_handle{ nullptr } {
|
DL::DL(const std::filesystem::path& dl) : m_handle{ nullptr } {
|
||||||
if (!path)
|
m_handle = dlopen(dl.c_str(), RTLD_NOW);
|
||||||
return;
|
|
||||||
|
|
||||||
m_handle = dlopen(path, RTLD_NOW);
|
|
||||||
|
|
||||||
// Try opening in cwd if library is not known system-wide
|
|
||||||
if (!m_handle) {
|
|
||||||
std::string cwd_path = std::string{ "./" } + std::string{ path };
|
|
||||||
m_handle = dlopen(cwd_path.c_str(), RTLD_NOW);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DL::~DL() {
|
DL::~DL() {
|
||||||
|
|||||||
108
src/install.cpp
Normal file
108
src/install.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "install.hpp"
|
||||||
|
#include "cli.hpp"
|
||||||
|
|
||||||
|
InstallManager::InstallManager(InstallManager&& other) noexcept {
|
||||||
|
m_valid = other.m_valid;
|
||||||
|
other.m_valid = false;
|
||||||
|
m_home_directory = std::move(other.m_home_directory);
|
||||||
|
m_install_directory = std::move(other.m_install_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager& InstallManager::operator=(InstallManager&& other) noexcept {
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
m_valid = other.m_valid;
|
||||||
|
other.m_valid = false;
|
||||||
|
m_home_directory = std::move(other.m_home_directory);
|
||||||
|
m_install_directory = std::move(other.m_install_directory);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager::InstallManager() : m_valid{ false } {
|
||||||
|
std::string hdstr;
|
||||||
|
if (!home_directory(hdstr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_home_directory = std::filesystem::path{ hdstr };
|
||||||
|
m_install_directory = m_home_directory / std::filesystem::path{ INSTALL_PATH };
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(m_install_directory) || !std::filesystem::is_directory(m_install_directory)) {
|
||||||
|
if (!std::filesystem::create_directories(m_install_directory))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager::~InstallManager() {}
|
||||||
|
|
||||||
|
InstallManager::operator bool() const {
|
||||||
|
return m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InstallManager::install(const char* from, const char* to) {
|
||||||
|
if (!m_valid || !from)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::filesystem::path src { from };
|
||||||
|
std::filesystem::path dst;
|
||||||
|
|
||||||
|
if (to) {
|
||||||
|
dst = std::filesystem::path{ to };
|
||||||
|
if (dst != dst.filename())
|
||||||
|
return false; // Wirekit name may not include a path
|
||||||
|
} else {
|
||||||
|
std::string src_name { src.filename() };
|
||||||
|
if (src_name.ends_with(".so"))
|
||||||
|
dst = std::filesystem::path{ src_name.substr(0, src_name.length() - 3) };
|
||||||
|
else
|
||||||
|
dst = std::filesystem::path{ src_name };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path install_dst = m_install_directory / dst;
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(src) || !std::filesystem::is_regular_file(src))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::filesystem::copy_file(src, install_dst, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InstallManager::uninstall(const char* name) {
|
||||||
|
if (!m_valid || !name)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::filesystem::path target { name };
|
||||||
|
if (target != target.filename())
|
||||||
|
return false; // Wirekit names never include paths (all are within/relative to installation directory)
|
||||||
|
|
||||||
|
std::filesystem::path install_target = m_install_directory / target;
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(install_target) || !std::filesystem::is_regular_file(install_target))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::filesystem::remove(install_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InstallManager::get(const char* name, std::filesystem::path& path) const {
|
||||||
|
if (!m_valid || !name)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::filesystem::path target { name };
|
||||||
|
if (target != target.filename())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
path = m_install_directory / target;
|
||||||
|
return std::filesystem::exists(path) && std::filesystem::is_regular_file(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<std::string> InstallManager::installs() const {
|
||||||
|
if (!m_valid)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::list<std::string> res;
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator{ m_install_directory })
|
||||||
|
res.emplace_back(entry.path().filename());
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
91
src/main.cpp
91
src/main.cpp
@ -1,7 +1,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "cli.hpp"
|
#include "cli.hpp"
|
||||||
#include "dl.hpp"
|
#include "dl.hpp"
|
||||||
|
#include "install.hpp"
|
||||||
|
|
||||||
int launch_help(int argc, char** argv) {
|
int launch_help(int argc, char** argv) {
|
||||||
std::cout << "Use rewire via one of the following commands:" << std::endl;
|
std::cout << "Use rewire via one of the following commands:" << std::endl;
|
||||||
@ -20,6 +22,7 @@ int launch_help(int argc, char** argv) {
|
|||||||
|
|
||||||
std::cout << " \"rewire <wirekit> <command+args>\"" << std::endl;
|
std::cout << " \"rewire <wirekit> <command+args>\"" << std::endl;
|
||||||
std::cout << " <wirekit> -> The wirekit to use for execution" << std::endl;
|
std::cout << " <wirekit> -> The wirekit to use for execution" << std::endl;
|
||||||
|
std::cout << " -> Can either be installed or in current working directory" << std::endl;
|
||||||
std::cout << " <command+args> -> (Optional) A command to be executed" << std::endl;
|
std::cout << " <command+args> -> (Optional) A command to be executed" << std::endl;
|
||||||
std::cout << " -> Acts as rewired shell if no command is given" << std::endl;
|
std::cout << " -> Acts as rewired shell if no command is given" << std::endl;
|
||||||
|
|
||||||
@ -27,18 +30,106 @@ int launch_help(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int launch_install(int argc, char** argv) {
|
int launch_install(int argc, char** argv) {
|
||||||
|
if (argc < 3 || argc > 4) {
|
||||||
|
std::cout << "Invalid usage, try \"rewire help\" for more information!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager im;
|
||||||
|
if (!im) {
|
||||||
|
std::cout << "Unable to manage installations!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!im.install(argv[2], (argc == 4 ? argv[3] : nullptr))) {
|
||||||
|
std::cout << "Failed to install wirekit!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Successfully installed wirekit!" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launch_uninstall(int argc, char** argv) {
|
int launch_uninstall(int argc, char** argv) {
|
||||||
|
if (argc != 3) {
|
||||||
|
std::cout << "Invalid usage, try \"rewire help\" for more information!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager im;
|
||||||
|
if (!im) {
|
||||||
|
std::cout << "Unable to manage installations!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!im.uninstall(argv[2])) {
|
||||||
|
std::cout << "Failed to uninstall wirekit!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Successfully uninstalled wirekit!" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launch_list(int argc, char** argv) {
|
int launch_list(int argc, char** argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cout << "Invalid usage, try \"rewire help\" for more information!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager im;
|
||||||
|
if (!im) {
|
||||||
|
std::cout << "Unable to access installations!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto wirekits = im.installs();
|
||||||
|
if (wirekits.empty()) {
|
||||||
|
std::cout << "Currently, no wirekits are installed!" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Currently, the following wirekits are installed:" << std::endl;
|
||||||
|
for (const std::string& kit : wirekits)
|
||||||
|
std::cout << " \"" << kit << "\"" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launch_run(int argc, char** argv) {
|
int launch_run(int argc, char** argv) {
|
||||||
|
if (argc < 2) {
|
||||||
|
std::cout << "Invalid usage, try \"rewire help\" for more information!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallManager im;
|
||||||
|
if (!im) {
|
||||||
|
std::cout << "Unable to access installations!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path wirekit_path;
|
||||||
|
if (!im.get(argv[1], wirekit_path)) {
|
||||||
|
std::cout << "No wirekit named \"" << argv[1] << "\" is installed!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DL wirekit { wirekit_path };
|
||||||
|
if (!wirekit) {
|
||||||
|
std::cout << "Unable to load wirekit!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO
|
||||||
|
environment.hpp/cpp
|
||||||
|
class Environment -> kit handles, hooks, trace contexts
|
||||||
|
class CommandScope -> hooks and trace contexts can only be added while scope holds environment, all cleared on scope exit
|
||||||
|
class TraceContext -> execution data on individual tracee threads
|
||||||
|
class TraceContextCollection -> management of all trace contexts and selection of active context
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO -> Execute single command (argc > 2) or shell
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user