Skip Unnecessary SDK Copying
This commit is contained in:
parent
bf24ace78e
commit
a80b5fb5c2
@ -40,7 +40,7 @@ include(cmake/options/paths.cmake)
|
||||
# Required Compile Flags
|
||||
string(CONCAT COMPILE_FLAGS_SETUP
|
||||
# Optimizations
|
||||
"if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n"
|
||||
"if(CMAKE_BUILD_TYPE MATCHES Release)\n"
|
||||
" add_compile_options(-O3)\n"
|
||||
" add_link_options(-s)\n"
|
||||
"else()\n"
|
||||
@ -169,27 +169,34 @@ if(BUILD_NATIVE_COMPONENTS)
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>")
|
||||
if(NOT MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
|
||||
if(DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE}")
|
||||
set(ARM_TOOLCHAIN "${CMAKE_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${MCPI_CMAKE_TOOLCHAIN_FILE}")
|
||||
set(ARM_TOOLCHAIN "${MCPI_CMAKE_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
if(DEFINED ARM_TOOLCHAIN)
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${ARM_TOOLCHAIN}")
|
||||
endif()
|
||||
list(APPEND ARM_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}")
|
||||
# Build
|
||||
ExternalProject_Add(arm-components
|
||||
# Source Directory
|
||||
DOWNLOAD_COMMAND ""
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
# Pass Arguments To CMake
|
||||
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
|
||||
# Install
|
||||
INSTALL_COMMAND
|
||||
"${CMAKE_COMMAND}" "-E"
|
||||
"rm" "-rf" "<INSTALL_DIR>/${MCPI_INSTALL_DIR}"
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" "-E" "env"
|
||||
"DESTDIR="
|
||||
"${CMAKE_COMMAND}" "-E" "env" "DESTDIR="
|
||||
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>"
|
||||
# Use Terminal
|
||||
USES_TERMINAL_CONFIGURE TRUE
|
||||
USES_TERMINAL_BUILD TRUE
|
||||
USES_TERMINAL_INSTALL TRUE
|
||||
# Always Build
|
||||
BUILD_ALWAYS TRUE
|
||||
)
|
||||
# Install
|
||||
|
@ -30,7 +30,7 @@ void bootstrap(const options_t &options) {
|
||||
|
||||
// Copy SDK
|
||||
if (!reborn_is_server()) {
|
||||
copy_sdk(binary_directory, true);
|
||||
copy_sdk(binary_directory, false);
|
||||
}
|
||||
|
||||
// Resolve Binary Path
|
||||
|
@ -42,36 +42,15 @@ static void load(std::vector<std::string> &ld_preload, const std::string &folder
|
||||
if (recursion_limit <= 0) {
|
||||
ERR("Reached Recursion Limit While Loading Mods");
|
||||
}
|
||||
// Open Folder
|
||||
// Make Directory
|
||||
ensure_directory(folder.c_str());
|
||||
DIR *dp = opendir(folder.c_str());
|
||||
if (dp == nullptr) {
|
||||
// Unable To Open Folder
|
||||
ERR("Error Opening Directory: %s: %s", folder.c_str(), strerror(errno));
|
||||
}
|
||||
// Loop Through Folder
|
||||
while (true) {
|
||||
errno = 0;
|
||||
const dirent *entry = readdir(dp);
|
||||
if (entry != nullptr) {
|
||||
// Block Pseudo-Directories
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
// Get Full Name
|
||||
std::string name = folder + entry->d_name;
|
||||
// Handle
|
||||
handle_file(ld_preload, name, recursion_limit);
|
||||
} else if (errno != 0) {
|
||||
// Error Reading Contents Of Folder
|
||||
ERR("Error Reading Directory: %s: %s", folder.c_str(), strerror(errno));
|
||||
} else {
|
||||
// Done!
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Close Folder
|
||||
closedir(dp);
|
||||
// Read
|
||||
read_directory(folder, [&folder, &ld_preload, &recursion_limit](const dirent *entry) {
|
||||
// Get Full Name
|
||||
const std::string name = folder + entry->d_name;
|
||||
// Handle
|
||||
handle_file(ld_preload, name, recursion_limit);
|
||||
});
|
||||
}
|
||||
|
||||
// Bootstrap Mods
|
||||
|
@ -41,7 +41,7 @@ static void setup_environment(const options_t &options) {
|
||||
static void handle_non_launch_commands(const options_t &options) {
|
||||
if (options.copy_sdk) {
|
||||
const std::string binary_directory = get_binary_directory();
|
||||
copy_sdk(binary_directory, false);
|
||||
copy_sdk(binary_directory, true);
|
||||
fflush(stdout);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -1,61 +1,166 @@
|
||||
#include <optional>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util/util.h>
|
||||
#include <libreborn/util/io.h>
|
||||
#include <libreborn/config.h>
|
||||
|
||||
#include "../bootstrap/bootstrap.h"
|
||||
#include "util.h"
|
||||
|
||||
// Utility Functions
|
||||
static constexpr char path_separator = '/';
|
||||
static void make_directory(std::string path /* Must Be Absolute */) {
|
||||
path += path_separator;
|
||||
std::stringstream stream(path);
|
||||
path = "";
|
||||
std::string path_segment;
|
||||
while (std::getline(stream, path_segment, path_separator)) {
|
||||
path += path_segment;
|
||||
ensure_directory(path.c_str());
|
||||
path += path_separator;
|
||||
}
|
||||
}
|
||||
static void delete_recursively(const std::string &path, const bool allow_nonexistent_dir) {
|
||||
// Loop Through Children
|
||||
const bool success = read_directory(path, [&path](const dirent *entry) {
|
||||
// Handle
|
||||
const std::string child = path + path_separator + entry->d_name;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
delete_recursively(child, false);
|
||||
} else if (unlink(child.c_str()) != 0) {
|
||||
ERR("Unable To Delete File: %s: %s", child.c_str(), strerror(errno));
|
||||
}
|
||||
}, allow_nonexistent_dir);
|
||||
// Delete
|
||||
if (success && rmdir(path.c_str()) != 0) {
|
||||
ERR("Unable To Delete Directory: %s: %s", path.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
static void copy_file(const std::string &src, const std::string &dst) {
|
||||
std::ifstream in(src, std::ios::binary);
|
||||
if (!in) {
|
||||
ERR("Unable To Open Source File: %s", src.c_str());
|
||||
}
|
||||
std::ofstream out(dst, std::ios::binary);
|
||||
if (!out) {
|
||||
ERR("Unable To Create Destination File: %s", dst.c_str());
|
||||
}
|
||||
out << in.rdbuf();
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
static void copy_directory(const std::string &src, const std::string &dst) {
|
||||
read_directory(src, [&src, &dst](const dirent *entry) {
|
||||
const std::string name = path_separator + std::string(entry->d_name);
|
||||
const std::string in = src + name;
|
||||
const std::string out = dst + name;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
ensure_directory(out.c_str());
|
||||
copy_directory(in, out);
|
||||
} else {
|
||||
copy_file(in, out);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Path
|
||||
static std::string get_sdk_root(const std::string &home) {
|
||||
return home + path_separator + "sdk";
|
||||
}
|
||||
static std::string get_sdk_path_home() {
|
||||
return get_sdk_root(home_get()) + path_separator + MCPI_SDK_DIR;
|
||||
}
|
||||
static std::string get_sdk_path_bundled(const std::string &binary_directory) {
|
||||
return get_sdk_root(binary_directory);
|
||||
}
|
||||
|
||||
// Test Whether SDK Should Be Copied
|
||||
static std::optional<std::string> get_sdk_hash(const std::string &sdk) {
|
||||
const std::string path = sdk + path_separator + ".hash";
|
||||
// Open File
|
||||
std::ifstream stream(path, std::ios::binary | std::ios::ate);
|
||||
if (stream) {
|
||||
std::string hash;
|
||||
// Read File
|
||||
const std::streamoff size = stream.tellg();
|
||||
stream.seekg(0, std::ifstream::beg);
|
||||
hash.resize(size);
|
||||
stream.read(hash.data(), size);
|
||||
// Close File
|
||||
stream.close();
|
||||
// Return
|
||||
return hash;
|
||||
} else {
|
||||
// Unable To Read
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
static bool should_copy_sdk(const std::string &binary_directory) {
|
||||
// Read Hashes
|
||||
const std::optional<std::string> home_hash = get_sdk_hash(get_sdk_path_home());
|
||||
if (!home_hash.has_value()) {
|
||||
return true;
|
||||
}
|
||||
const std::optional<std::string> bundled_hash = get_sdk_hash(get_sdk_path_bundled(binary_directory));
|
||||
if (!home_hash.has_value()) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
const bool should_copy = home_hash.value() != bundled_hash.value();
|
||||
if (!should_copy) {
|
||||
DEBUG("Skipped Unnecessary SDK Copy");
|
||||
}
|
||||
return should_copy;
|
||||
}
|
||||
|
||||
// Log
|
||||
#define LOG(is_debug, ...) \
|
||||
{ \
|
||||
if (is_debug) { \
|
||||
({ \
|
||||
if ((is_debug)) { \
|
||||
DEBUG(__VA_ARGS__); \
|
||||
} else { \
|
||||
INFO(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
})
|
||||
|
||||
// Copy SDK Into ~/.minecraft-pi
|
||||
#define HOME_SUBDIRECTORY_FOR_SDK "/sdk"
|
||||
void copy_sdk(const std::string &binary_directory, const bool log_with_debug) {
|
||||
// Ensure SDK Directory
|
||||
std::string sdk_path;
|
||||
{
|
||||
sdk_path = home_get() + HOME_SUBDIRECTORY_FOR_SDK;
|
||||
const char *const command[] = {"mkdir", "-p", sdk_path.c_str(), nullptr};
|
||||
run_simple_command(command, "Unable To Create SDK Directory");
|
||||
static void do_copy_sdk(const std::string &binary_directory, const bool force) {
|
||||
// Check If Copy Is Needed
|
||||
bool should_copy = force;
|
||||
if (!should_copy) {
|
||||
should_copy = should_copy_sdk(binary_directory);
|
||||
}
|
||||
if (!should_copy) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Lock File
|
||||
const std::string lock_file_path = sdk_path + "/.lock";
|
||||
const int lock_file_fd = lock_file(lock_file_path.c_str());
|
||||
// Get Paths
|
||||
const std::string src_sdk = get_sdk_path_bundled(binary_directory);
|
||||
const std::string dst_sdk = get_sdk_path_home();
|
||||
|
||||
// Output Directory
|
||||
const std::string output = sdk_path + "/" MCPI_SDK_DIR;
|
||||
// Source Directory
|
||||
const std::string source = binary_directory + "/sdk/.";
|
||||
// Create Output Directory
|
||||
delete_recursively(dst_sdk, true);
|
||||
make_directory(dst_sdk);
|
||||
|
||||
// Clean
|
||||
{
|
||||
const char *const command[] = {"rm", "-rf", output.c_str(), nullptr};
|
||||
run_simple_command(command, "Unable To Clean SDK Output Directory");
|
||||
}
|
||||
|
||||
// Make Directory
|
||||
{
|
||||
const char *const command[] = {"mkdir", "-p", output.c_str(), nullptr};
|
||||
run_simple_command(command, "Unable To Create SDK Output Directory");
|
||||
}
|
||||
|
||||
// Copy
|
||||
{
|
||||
const char *const command[] = {"cp", "-ar", source.c_str(), output.c_str(), nullptr};
|
||||
run_simple_command(command, "Unable To Copy SDK");
|
||||
}
|
||||
// Copy Directory
|
||||
copy_directory(src_sdk, dst_sdk);
|
||||
|
||||
// Log
|
||||
LOG(log_with_debug, "Copied SDK To: %s", output.c_str());
|
||||
LOG(!force, "Copied SDK To: %s", dst_sdk.c_str());
|
||||
}
|
||||
void copy_sdk(const std::string &binary_directory, const bool force) {
|
||||
// Lock File
|
||||
const std::string root = get_sdk_root(home_get());
|
||||
ensure_directory(root.c_str());
|
||||
const std::string lock_file_path = root + path_separator + ".lock";
|
||||
const int lock_file_fd = lock_file(lock_file_path.c_str());
|
||||
|
||||
// Do
|
||||
do_copy_sdk(binary_directory, force);
|
||||
|
||||
// Unlock File
|
||||
unlock_file(lock_file_path.c_str(), lock_file_fd);
|
||||
|
@ -1,18 +1,11 @@
|
||||
#include <dirent.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <libreborn/log.h>
|
||||
#include <libreborn/util/exec.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
// Simpler Version Of run_command()
|
||||
void run_simple_command(const char *const command[], const char *error) {
|
||||
int status = 0;
|
||||
const std::vector<unsigned char> *output = run_command(command, &status);
|
||||
delete output;
|
||||
if (!is_exit_status_success(status)) {
|
||||
ERR("%s", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Chop Off Last Component
|
||||
void chop_last_component(std::string &str) {
|
||||
const std::string::size_type pos = str.find_last_of('/');
|
||||
@ -40,3 +33,28 @@ std::string get_binary_directory() {
|
||||
// Return
|
||||
return exe;
|
||||
}
|
||||
|
||||
// Read Directory
|
||||
bool read_directory(const std::string &path, const std::function<void(const dirent *)> &callback, const bool allow_nonexistent_dir) {
|
||||
// Open Directory
|
||||
DIR *dp = opendir(path.c_str());
|
||||
if (dp == nullptr) {
|
||||
if (allow_nonexistent_dir) {
|
||||
return false;
|
||||
}
|
||||
ERR("Unable To Open Directory: %s: %s", path.c_str(), strerror(errno));
|
||||
}
|
||||
// Read
|
||||
const dirent *entry;
|
||||
while ((entry = readdir(dp)) != nullptr) {
|
||||
// Block Pseudo-Directories
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
// Run
|
||||
callback(entry);
|
||||
}
|
||||
// Close
|
||||
closedir(dp);
|
||||
return true;
|
||||
}
|
@ -1,14 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
void run_simple_command(const char *const command[], const char *error);
|
||||
#include <functional>
|
||||
|
||||
void chop_last_component(std::string &str);
|
||||
std::string safe_realpath(const std::string &path);
|
||||
std::string get_binary_directory();
|
||||
|
||||
void copy_sdk(const std::string &binary_directory, bool log_with_debug);
|
||||
void copy_sdk(const std::string &binary_directory, bool force);
|
||||
|
||||
void setup_path();
|
||||
void setup_home();
|
||||
|
||||
bool read_directory(const std::string &path, const std::function<void(const struct dirent *)> &callback, bool allow_nonexistent_dir = false);
|
@ -86,11 +86,14 @@ const char *get_home_subdirectory_for_game_data() {
|
||||
|
||||
// Make Sure Directory Exists
|
||||
void ensure_directory(const char *path) {
|
||||
if (path[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
int ret = mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
if (ret != 0 && errno != EEXIST) {
|
||||
ERR("Unable To Create Directory: %s", strerror(errno));
|
||||
ERR("Unable To Create Directory: %s: %s", path, strerror(errno));
|
||||
}
|
||||
int is_dir = 0;
|
||||
bool is_dir = false;
|
||||
struct stat obj = {};
|
||||
ret = stat(path, &obj);
|
||||
if (ret == 0) {
|
||||
|
@ -105,8 +105,10 @@ static bool is_whitelist() {
|
||||
}
|
||||
// Get Path Of Blacklist (Or Whitelist) File
|
||||
static std::string get_blacklist_file() {
|
||||
std::string file(home_get());
|
||||
file.append(is_whitelist() ? "/whitelist.txt" : "/blacklist.txt");
|
||||
std::string file = home_get();
|
||||
file += '/';
|
||||
file += is_whitelist() ? "whitelist" : "blacklist";
|
||||
file += ".txt";
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -418,20 +420,16 @@ static bool is_ip_in_blacklist(const char *ip) {
|
||||
ips.clear();
|
||||
// Check banned-ips.txt
|
||||
const std::string blacklist_file_path = get_blacklist_file();
|
||||
std::ifstream blacklist_file(blacklist_file_path);
|
||||
std::ifstream blacklist_file(blacklist_file_path, std::ios::binary);
|
||||
if (blacklist_file) {
|
||||
if (blacklist_file.good()) {
|
||||
std::string line;
|
||||
while (std::getline(blacklist_file, line)) {
|
||||
// Check Line
|
||||
if (line.length() > 0 && line[0] != '#') {
|
||||
ips.push_back(line);
|
||||
}
|
||||
std::string line;
|
||||
while (std::getline(blacklist_file, line)) {
|
||||
// Check Line
|
||||
if (line.length() > 0 && line[0] != '#') {
|
||||
ips.push_back(line);
|
||||
}
|
||||
}
|
||||
if (blacklist_file.is_open()) {
|
||||
blacklist_file.close();
|
||||
}
|
||||
blacklist_file.close();
|
||||
} else {
|
||||
ERR("Unable To Read Blacklist/Whitelist");
|
||||
}
|
||||
@ -523,10 +521,10 @@ static void server_init() {
|
||||
// Open Properties File
|
||||
std::string file(home_get());
|
||||
file.append("/server.properties");
|
||||
std::ifstream properties_file(file);
|
||||
std::ifstream properties_file(file, std::ios::binary);
|
||||
|
||||
// Check Properties File
|
||||
if (!properties_file.good()) {
|
||||
if (!properties_file) {
|
||||
// Write Defaults
|
||||
std::ofstream properties_file_output(file);
|
||||
get_property_types();
|
||||
@ -536,12 +534,12 @@ static void server_init() {
|
||||
}
|
||||
properties_file_output.close();
|
||||
// Re-Open File
|
||||
properties_file = std::ifstream(file);
|
||||
properties_file = std::ifstream(file, std::ios::binary);
|
||||
}
|
||||
|
||||
// Check Properties File
|
||||
if (!properties_file.is_open()) {
|
||||
ERR("Unable To Open %s", file.c_str());
|
||||
if (!properties_file) {
|
||||
ERR("Unable To Read Server Properties");
|
||||
}
|
||||
// Load Properties
|
||||
get_server_properties().load(properties_file);
|
||||
@ -550,16 +548,12 @@ static void server_init() {
|
||||
|
||||
// Create Empty Blacklist/Whitelist File
|
||||
std::string blacklist_file_path = get_blacklist_file();
|
||||
std::ifstream blacklist_file(blacklist_file_path);
|
||||
if (!blacklist_file.good()) {
|
||||
if (access(blacklist_file_path.c_str(), F_OK) != 0) {
|
||||
// Write Default
|
||||
std::ofstream blacklist_output(blacklist_file_path);
|
||||
blacklist_output << "# Blacklist/Whitelist; Each Line Is One IP Address\n";
|
||||
blacklist_output.close();
|
||||
}
|
||||
if (blacklist_file.is_open()) {
|
||||
blacklist_file.close();
|
||||
}
|
||||
// Load Blacklist/Whitelist
|
||||
is_ip_in_blacklist(nullptr);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user