M .build.yml => .build.yml +2 -0
@@ 5,6 5,8 @@ packages:
- libefiboot-dev
- libssl-dev
tasks:
+ - cmdline: |
+ cat /proc/cmdline
- build-gcc: |
cd klapki
make
M Makefile => Makefile +3 -46
@@ 34,7 34,7 @@ TEST_SOURCES := $(sort $(wildcard $(TSTDIR)*.cpp $(TSTDIR)**/*.cpp $(TSTDIR)**/*
LIBFMT := $(patsubst ext/fmt/src/%.cc,$(BLDDIR)fmt/obj/%$(OBJ),$(wildcard ext/fmt/src/*.cc))
-.PHONY : all clean build build-test audiere cpp-localiser cpr fmt seed11 semver zstd whereami-cpp
+.PHONY : all clean build build-test fmt
all : fmt build build-test test
@@ 45,8 45,8 @@ test: build-test
clean :
rm -rf $(OUTDIR)
-build : audiere cpp-localiser cpr seed11 fmt seed11 semver whereami-cpp zstd $(OUTDIR)klapki$(EXE)
-build-test : audiere cpp-localiser cpr seed11 fmt seed11 semver whereami-cpp zstd $(OUTDIR)klapki-test$(EXE)
+build : fmt $(OUTDIR)klapki$(EXE)
+build-test : fmt $(OUTDIR)klapki-test$(EXE)
fmt : $(LIBFMT)
@@ 57,37 57,6 @@ $(OUTDIR)klapki$(EXE) : $(subst $(SRCDIR),$(OBJDIR),$(subst .cpp,$(OBJ),$(SOURCE
$(OUTDIR)klapki-test$(EXE) : $(subst $(TSTDIR),$(BLDDIR)test/,$(subst .cpp,$(OBJ),$(TEST_SOURCES))) $(subst $(SRCDIR),$(OBJDIR),$(subst .cpp,$(OBJ),$(filter-out $(SRCDIR)main.cpp,$(SOURCES)))) $(patsubst ext/fmt/src/%.cc,$(BLDDIR)fmt/obj/%$(OBJ),$(wildcard ext/fmt/src/*.cc))
$(CXX) $(CXXAR) -o$@ $^ $(PIC) $(LDAR)
-$(BLDDIR)audiere/lib/libaudiere$(DLL) : ext/audiere/CMakeLists.txt
- @mkdir -p $(abspath $(dir $@)../build)
- # FLAC doesn't seem to work on Travis by default so v0v
- cd $(abspath $(dir $@)../build) && $(INCCMAKEAR) $(LNCMAKEAR) $(CMAKE) -DUSE_FLAC=OFF -DCMAKE_INSTALL_PREFIX:PATH="$(abspath $(dir $@)..)" $(abspath $(dir $^)) -GNinja
- cd $(abspath $(dir $@)../build) && $(NINJA) install
- $(if $(OS) | grep Windows_NT,cp $@ $(OUTDIR))
-
-$(BLDDIR)cpp-localiser/libcpp-localiser$(ARCH) : ext/cpp-localiser/Makefile
- $(MAKE) -C$(dir $^) BUILD=$(abspath $(dir $@)) stlib
-
-$(BLDDIR)seed11/libseed11$(ARCH) : $(foreach src,seed11_system_agnostic seed11_$(SEED11_SYSTEM_TYPE) deterministic_unsafe_seed_device,$(BLDDIR)seed11/obj/$(src)$(OBJ))
- $(AR) crs $@ $^
-
-$(BLDDIR)semver/libsemver$(ARCH) : $(patsubst ext/semver/src/%.cpp,$(BLDDIR)semver/obj/%$(OBJ),$(wildcard ext/semver/src/*.cpp))
- $(AR) crs $@ $^
-
-$(BLDDIR)semver/include/semver/semver200.h : $(wildcard ext/semver/include/*.h ext/semver/include/*.inl)
- @mkdir -p $(dir $@)
- cp $^ $(dir $@)
-
-$(BLDDIR)whereami-cpp/libwhereami++$(ARCH) : ext/whereami-cpp/Makefile
- $(MAKE) -C$(dir $^) BUILD=$(abspath $(dir $@)) stlib
-
-$(BLDDIR)zstd/libzstd$(ARCH) : $(subst ext/zstd/lib,$(BLDDIR)zstd/obj,$(subst .c,$(OBJ),$(wildcard ext/zstd/lib/common/*.c ext/zstd/lib/compress/*.c ext/zstd/lib/decompress/*.c)))
- @mkdir -p $(dir $@)
- $(AR) crs $@ $^
-
-$(BLDDIR)zstd/include/zstd/zstd.h : $(wildcard ext/zstd/lib/*.h ext/zstd/lib/common/*.h ext/zstd/lib/compress/*.h ext/zstd/lib/decompress/*.h)
- @mkdir -p $(foreach incfile,$(subst ext/zstd/lib,$(BLDDIR)zstd/include/zstd,$^),$(abspath $(dir $(incfile))))
- $(foreach incfile,$^,cp $(incfile) $(subst ext/zstd/lib,$(BLDDIR)zstd/include/zstd,$(incfile));)
-
$(OBJDIR)%$(OBJ) : $(SRCDIR)%.cpp
@mkdir -p $(dir $@)
@@ 100,15 69,3 @@ $(BLDDIR)test/%$(OBJ) : $(TSTDIR)%.cpp
$(BLDDIR)fmt/obj/%$(OBJ) : ext/fmt/src/%.cc
@mkdir -p $(dir $@)
$(CXX) $(CXXAR) -Iext/fmt/include -c -o$@ $^
-
-#$(BLDDIR)semver/obj/%$(OBJ) : ext/semver/src/%.cpp
-# @mkdir -p $(dir $@)
-# $(CXX) $(CXXAR) -Iext/semver/include -c -o$@ $^
-#
-#$(BLDDIR)seed11/obj/%$(OBJ) : ext/seed11/src/%.cpp
-# @mkdir -p $(dir $@)
-# $(CXX) $(CXXAR) -isystemext/seed11/include -c -o$@ $^
-#
-#$(BLDDIR)zstd/obj/%$(OBJ) : ext/zstd/lib/%.c
-# @mkdir -p $(dir $@)
-# $(CC) $(CCAR) -Iext/zstd/lib -Iext/zstd/lib/common -c -o$@ $^
M configMakefile => configMakefile +1 -2
@@ 46,7 46,7 @@ else
LNCXXAR :=
endif
-#KLAPKI_VERSION := "$(patsubst v%,%,$(shell git describe --tags --abbrev=0))"
+#KLAPKI_VERSION := "$(patsubst v%,%,$(shell git describe))"
KLAPKI_VERSION := "0.0.0-$(shell git rev-list HEAD --count)"
INCCMAKEAR := CXXFLAGS="$(INCCXXAR)"
@@ 56,7 56,6 @@ OBJ := .o
ARCH := .a
AR := ar
CXXAR := -O3 -std=c++17 -Wall -Wextra $(PEDANTIC) -pipe $(INCCXXAR) $(PIC)
-CCAR := -O3 -fomit-frame-pointer -std=c11 -pipe $(PIC)
STRIP := strip
STRIPAR := --strip-all --remove-section=.comment --remove-section=.note
M src/config.cpp => src/config.cpp +27 -8
@@ 24,6 24,7 @@
#include "util.hpp"
#include <cstdlib>
#include <fmt/format.h>
+#include <fstream>
#include <limits.h>
#include <sys/stat.h>
#include <sys/utsname.h>
@@ 42,11 43,18 @@ extern "C" {
})
+static std::string readline(const char * from) {
+ std::ifstream in(from);
+ std::string ret;
+ std::getline(in, ret);
+ return ret;
+}
+
static std::string get_host() {
if(auto host = std::getenv("KLAPKI_HOST"))
return host;
else {
- auto mid = klapki::readline("/etc/machine-id");
+ auto mid = readline("/etc/machine-id");
if(!mid.empty())
return mid;
@@ 112,8 120,9 @@ std::variant<klapki::config, std::string> klapki::config::read(const char ** arg
const auto argv0 = argv[0];
++argv;
- bool verbose = false;
- bool commit = true;
+ bool verbose = false;
+ bool verybose = false;
+ bool commit = true;
for(; *argv && argv[0][0] == '-'; ++argv) {
for(auto opts = argv[0] + 1; *opts; ++opts)
switch(opts[0]) {
@@ 121,6 130,10 @@ std::variant<klapki::config, std::string> klapki::config::read(const char ** arg
verbose = true;
break;
+ case 'V':
+ verybose = true;
+ break;
+
case 'E':
efi_set_verbose(efi_get_verbose() + 1, nullptr);
break;
@@ 131,14 144,20 @@ std::variant<klapki::config, std::string> klapki::config::read(const char ** arg
case 'h':
return fmt::format("klapki {}\n"
- "Usage: {} [-vEnh]… [op [arg…]]…\n"
+ "Usage: {} [-nvVEh]… [op [arg…]]…\n"
"\n"
"Flags:\n"
+ " -n\tDon't commit\n"
" -v\tVerbose operation\n"
+ " -V\tAdd {{dump}}s around all ops\n"
" -E\tIncrease libefivar verbosity level\n"
- " -n\tDon't commit\n"
" -h\tShow this help\n"
"\n"
+ "Environment:\n"
+ " KLAPKI_HOST= \tReplaces contents of /etc/machine-id or hostname\n"
+ " KLAPKI_WISDOM= \tReplaces /etc/klapki\n"
+ " KLAPKI_EFI_ROOT=\tReplaces \\klapki\n"
+ "\n"
"Recognised ops:\n"
"\tdump\n"
"\tbootpos <position>\n"
@@ 154,7 173,7 @@ std::variant<klapki::config, std::string> klapki::config::read(const char ** arg
}
std::vector<ops::op_t> ops;
- if(verbose)
+ if(verybose)
ops.emplace_back(ops::dump{});
while(*argv) {
auto pop = op::from_cmdline(argv0, argv);
@@ 162,10 181,10 @@ std::variant<klapki::config, std::string> klapki::config::read(const char ** arg
return std::move(*err);
else {
ops.emplace_back(std::move(std::get<ops::op_t>(pop)));
- if(verbose)
+ if(verybose)
ops.emplace_back(ops::dump{});
}
}
- return config{argv0, get_host(), verbose, commit, TRY(find_esp()), std::move(ops), get_wisom_root()};
+ return config{get_host(), verbose, commit, TRY(find_esp()), std::move(ops), get_wisom_root()};
}
M src/config.hpp => src/config.hpp +0 -1
@@ 32,7 32,6 @@
namespace klapki {
struct config {
- const char * argv0;
std::string host;
constexpr std::string_view wisdom_root() const noexcept;
bool verbose;
M src/context_derive.cpp => src/context_derive.cpp +11 -0
@@ 32,6 32,17 @@ extern "C" {
}
+namespace {
+ /// unique_ptr deleter that uses free(3)
+ struct free_deleter {
+ template <class T>
+ void operator()(T * ptr) const noexcept {
+ std::free(ptr);
+ }
+ };
+}
+
+
klapki::context::context klapki::context::context::derive(const config & cfg, state::state & output_state) {
context ret{};
M src/main.cpp => src/main.cpp +1 -1
@@ 51,7 51,7 @@ namespace klapki {
fmt::print("{}\n", cfg);
- const auto input_state = TRY(2, state::state::load(cfg.argv0, cfg.host));
+ const auto input_state = TRY(2, state::state::load(cfg.host));
auto output_state = TRY(3, context::resolve_state_context(cfg, input_state));
M src/state.cpp => src/state.cpp +12 -11
@@ 95,15 95,16 @@ static int get_boot_entry(std::map<std::uint16_t, klapki::state::boot_entry> & b
}
static int get_our_config(klapki::state::stated_config & statecfg, std::string_view us) {
- return get_efi_data(klapki::efi_guid_klapki, us.data(),
- // TODO: error recovery; flag to ignore? force?
- [&](auto && data, auto size, auto) { return klapki::state::stated_config::parse(statecfg, data.get(), size); });
+ return get_efi_data(klapki::efi_guid_klapki, us.data(), [&](auto && data, auto size, auto) {
+ klapki::state::stated_config::parse(statecfg, data.get(), size);
+ return 0;
+ });
}
-std::variant<klapki::state::state, std::string> klapki::state::state::load(const char * argv0, std::string_view us) {
+std::variant<klapki::state::state, std::string> klapki::state::state::load(std::string_view us) {
if(!efi_variables_supported())
- return fmt::format("{}: EFI not supported?", argv0);
+ return fmt::format("EFI not supported?");
std::vector<std::uint16_t> boot_entries;
@@ 118,29 119,29 @@ std::variant<klapki::state::state, std::string> klapki::state::state::load(const
else if(is_our_config(guid, name, us))
have_our_config = true;
}))
- return fmt::format("{}: klapki::state::state::load(): iteration: {}", argv0, strerror(res)); // No threads here, and we avoid a strerror_r() clusterfuck
+ return fmt::format("EFI load: klapki::state::state::load(): iteration: {}", strerror(res)); // No threads here, and we avoid a strerror_r() clusterfuck
boot_order_flat bord{};
if(have_boot_order) {
if(get_boot_order(bord) < 0)
- return fmt::format("{}: klapki::state::state::load(): getting BootOrder: {}", argv0, strerror(errno));
+ return fmt::format("EFI load: getting BootOrder: {}", strerror(errno));
} else
- fmt::print(stderr, "{}: no BootOrder?\n", argv0);
+ fmt::print(stderr, "EFI: no BootOrder?\n");
std::map<std::uint16_t, boot_entry> entries;
for(auto bent : boot_entries)
if(get_boot_entry(entries, bent) < 0)
- return fmt::format("{}: klapki::state::state::load(): getting Boot{:04X}: {}", argv0, bent, strerror(errno));
+ return fmt::format("EFI load: getting Boot{:04X}: {}", bent, strerror(errno));
stated_config statecfg{};
if(have_our_config) {
if(get_our_config(statecfg, us) < 0)
- return fmt::format("{}: klapki::state::state::load(): getting {}-{}: {}", argv0, efi_guid_klapki_s, us, strerror(errno));
+ return fmt::format("EFI load: getting {}-{}: {}", efi_guid_klapki_s, us, strerror(errno));
} else
- fmt::print(stderr, "{}: no config for this host ({}) found; going to the top\n", argv0, us);
+ fmt::print(stderr, "EFI load: no config for this host ({}) found; going to the top\n", us);
return state{std::move(bord), std::move(entries), std::move(statecfg)};
}
M src/state.hpp => src/state.hpp +2 -3
@@ 79,8 79,7 @@ namespace klapki::state {
std::vector<std::string> variants; // entries NUL-terminated; list empty-terminated; kept unique, order-preserving
std::vector<stated_config_entry> wanted_entries;
- /// 0 on OK, errno on error
- static int parse(stated_config & into, const void * data, std::size_t size);
+ static void parse(stated_config & into, const void * data, std::size_t size);
std::vector<std::uint8_t> serialise() const;
@@ 96,7 95,7 @@ namespace klapki::state {
std::optional<std::string> commit(std::string_view us, const state & original_state) const;
- static std::variant<state, std::string> load(const char * argv0, std::string_view us);
+ static std::variant<state, std::string> load(std::string_view us);
};
}
M src/state_config.cpp => src/state_config.cpp +13 -15
@@ 29,10 29,10 @@
#define SUB "\x1A"
-int klapki::state::stated_config::parse(klapki::state::stated_config & into, const void * _data, std::size_t size) {
+void klapki::state::stated_config::parse(klapki::state::stated_config & into, const void * _data, std::size_t size) {
if(size < 2) {
- errno = ENODATA;
- return -1;
+ fmt::print(stderr, "Parsing state: cut off before boot position\n");
+ return;
}
const char * data = reinterpret_cast<const char *>(_data);
@@ 44,7 44,7 @@ int klapki::state::stated_config::parse(klapki::state::stated_config & into, con
for(;;) {
const auto variant_end = std::find_if(data, data + size, [](auto b) { return b == '\0'; });
if(variant_end == data + size) {
- fmt::print(stderr, "extraneous data; -1\n");
+ fmt::print(stderr, "Parsing state: cut off after {} variant{}\n", into.variants.size(), into.variants.size() == 1 ? "" : "s");
data = data + size;
size = 0;
break;
@@ 68,7 68,7 @@ int klapki::state::stated_config::parse(klapki::state::stated_config & into, con
while(size != 0) {
stated_config_entry new_entry{};
if(size <= sizeof(new_entry.bootnum_hint) + sizeof(new_entry.load_option_sha)) {
- fmt::print(stderr, "extraneous data; 0\n");
+ fmt::print(stderr, "Parsing state: cut off after {} entr{}\n", into.wanted_entries.size(), into.wanted_entries.size() == 1 ? "y" : "ies");
break;
}
@@ 83,36 83,33 @@ int klapki::state::stated_config::parse(klapki::state::stated_config & into, con
const auto kver_end = std::find_if(data, data + size, [](auto b) { return b == '\0'; });
if(kver_end == data + size) {
- fmt::print(stderr, "extraneous data; 0.5; have: {:04X}\n", new_entry.bootnum_hint);
+ fmt::print(stderr, "Parsing state: cut off reading kernel version for entry {:04X}\n", new_entry.bootnum_hint);
break;
}
new_entry.version.assign(data, kver_end - data);
data += new_entry.version.size() + 1; // NUL
size -= new_entry.version.size() + 1; // NUL
- // fmt::print(stderr, "version: {} ({})\n", new_entry.version, new_entry.version.size());
const auto kvar_end = std::find_if(data, data + size, [](auto b) { return b == '\0'; });
if(kvar_end == data + size) {
- fmt::print(stderr, "extraneous data; 0.75; have: {:04X}\n", new_entry.bootnum_hint);
+ fmt::print(stderr, "Parsing state: cut off reading kernel variant for entry {:04X}\n", new_entry.bootnum_hint);
break;
}
new_entry.variant.assign(data, kvar_end - data);
data += new_entry.variant.size() + 1; // NUL
size -= new_entry.variant.size() + 1; // NUL
- // fmt::print(stderr, "kernel: {} ({})\n", new_entry.variant, new_entry.variant.size());
const auto kdir_end = std::find_if(data, data + size, [](auto b) { return b == '\0'; });
if(kdir_end == data + size) {
- fmt::print(stderr, "extraneous data; 1; have: {:04X}\n", new_entry.bootnum_hint);
+ fmt::print(stderr, "Parsing state: cut off reading kernel image directory for entry {:04X}\n", new_entry.bootnum_hint);
break;
}
new_entry.kernel_dirname.assign(data, kdir_end - data);
data += new_entry.kernel_dirname.size() + 1; // NUL
size -= new_entry.kernel_dirname.size() + 1; // NUL
- // fmt::print(stderr, "variant: {} ({})\n", new_entry.kernel_dirname, new_entry.kernel_dirname.size());
if(size <= sizeof(new_entry.kernel_image_sha)) {
- fmt::print(stderr, "extraneous data; 1.5\n");
+ fmt::print(stderr, "Parsing state: cut off reading kernel image SHA for entry {:04X}\n", new_entry.bootnum_hint);
break;
}
memcpy(&new_entry.kernel_image_sha, data, sizeof(new_entry.kernel_image_sha));
@@ 122,7 119,8 @@ int klapki::state::stated_config::parse(klapki::state::stated_config & into, con
for(;;) {
const auto idir_end = std::find_if(data, data + size, [](auto b) { return b == '\0'; });
if(idir_end == data + size) {
- fmt::print(stderr, "extraneous data; 2\n");
+ fmt::print(stderr, "Parsing state: cut off after {} initrd{} for entry {:04X}\n", new_entry.bootnum_hint, new_entry.initrd_dirnames.size(),
+ new_entry.initrd_dirnames.size() == 1 ? "" : "s");
goto end; // break outer loop; 2020 and C++ does not have this
}
@@ 135,7 133,7 @@ int klapki::state::stated_config::parse(klapki::state::stated_config & into, con
shaa_t idir_sha;
if(size <= idir_sha.size()) {
- fmt::print(stderr, "extraneous data; 2.5\n");
+ fmt::print(stderr, "Parsing state: cut off reading SHA for initrd {} for entry {:04X}\n", new_entry.bootnum_hint, new_entry.initrd_dirnames.size());
break;
}
memcpy(&idir_sha[0], data, idir_sha.size());
@@ 152,7 150,7 @@ int klapki::state::stated_config::parse(klapki::state::stated_config & into, con
}
end:
- return 0;
+ return;
}
D src/util.cpp => src/util.cpp +0 -32
@@ 1,32 0,0 @@
-// The MIT License (MIT)
-
-// Copyright (c) 2020 наб <nabijaczleweli@nabijaczleweli.xyz>
-
-// Permission is hereby granted, free of charge, to any person obtaining a copy of
-// this software and associated documentation files (the "Software"), to deal in
-// the Software without restriction, including without limitation the rights to
-// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-// the Software, and to permit persons to whom the Software is furnished to do so,
-// subject to the following conditions:
-
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-#include "util.hpp"
-#include <fstream>
-
-
-std::string klapki::readline(const char * from) {
- std::ifstream in(from);
- std::string ret;
- std::getline(in, ret);
- return ret;
-}
M src/util.hpp => src/util.hpp +0 -14
@@ 23,13 23,7 @@
#pragma once
-#include <cstdlib>
-#include <string>
-
-
namespace klapki {
- std::string readline(const char * from);
-
/// Stolen from https://en.cppreference.com/w/cpp/utility/variant/visit
template <class... Ts>
struct overload : Ts... {
@@ 37,12 31,4 @@ namespace klapki {
};
template <class... Ts>
overload(Ts...)->overload<Ts...>;
-
- /// unique_ptr deleter that uses free(3)
- struct free_deleter {
- template <class T>
- void operator()(T * ptr) const noexcept {
- std::free(ptr);
- }
- };
}
M test/state_parse.cpp => test/state_parse.cpp +7 -7
@@ 94,14 94,14 @@ static std::unordered_map<const char *, klapki::state::stated_config> states = {
TEST_CASE("klapki::state::stated_config::parse() ENODATA", "[klapki::state::stated_config::parse]") {
klapki::state::stated_config clean{};
+ clean.boot_position = __LINE__;
+ auto cclean = clean;
- REQUIRE(klapki::state::stated_config::parse(clean, nullptr, 0) == -1);
- REQUIRE(errno == ENODATA);
- REQUIRE(clean == klapki::state::stated_config{});
+ klapki::state::stated_config::parse(clean, nullptr, 0);
+ REQUIRE(clean == cclean);
- REQUIRE(klapki::state::stated_config::parse(clean, nullptr, 1) == -1);
- REQUIRE(errno == ENODATA);
- REQUIRE(clean == klapki::state::stated_config{});
+ klapki::state::stated_config::parse(clean, nullptr, 1);
+ REQUIRE(clean == cclean);
}
TEST_CASE("klapki::state::stated_config::parse() okay", "[klapki::state::stated_config::parse]") {
@@ 110,7 110,7 @@ TEST_CASE("klapki::state::stated_config::parse() okay", "[klapki::state::stated_
const auto indata = klapki::test::read_file(std::string{"test-data/state_parse/"} + name);
klapki::state::stated_config incfg{};
- REQUIRE(klapki::state::stated_config::parse(incfg, indata.data(), indata.size()) == 0);
+ klapki::state::stated_config::parse(incfg, indata.data(), indata.size());
// for(auto && ent : incfg.wanted_entries)
// fmt::print(stderr,
// "\tbootnum_hint: {}\n"