~nabijaczleweli/klapki

893993d258064e9afd8c5fe9f60ba92e76233899 — наб 1 year, 4 days ago a670da8
ive done other things today, what an accomplishment!
M src/config.hpp => src/config.hpp +0 -1
@@ 26,7 26,6 @@
#include "ops.hpp"
#include <string>
#include <string_view>
#include <sys/sysmacros.h>
#include <variant>
#include <vector>


M src/context_derive.cpp => src/context_derive.cpp +21 -15
@@ 77,18 77,19 @@ klapki::context::context klapki::context::context::derive(state::state & output_
					// TODO: drop this from the state entirely
					continue;
				case 1: {
					if(dp->type != EFIDP_MEDIA_TYPE) {
					if(file->type != EFIDP_MEDIA_TYPE) {
						fmt::print(stderr, "Entry {:04X} file not Media Device Path. Dropping.\n", went.bootnum_hint);
						// TODO: drop this from the state entirely
						continue;
					}
					if(dp->subtype != EFIDP_MEDIA_FILE) {
					if(file->subtype != EFIDP_MEDIA_FILE) {
						fmt::print(stderr, "Entry {:04X} file not Media Device Path File. Dropping.\n", went.bootnum_hint);
						// TODO: drop this from the state entirely
						continue;
					}

					const std::unique_ptr<char[], free_deleter> path_c{reinterpret_cast<char *>(ucs2_to_utf8(reinterpret_cast<char16_t *>(dp->file.name), dp->length))};
					const std::unique_ptr<char[], free_deleter> path_c{
					    reinterpret_cast<char *>(ucs2_to_utf8(reinterpret_cast<const char16_t *>(file->file.name), file->length))};
					std::string_view path{path_c.get()};
					if(const auto last_backslash = path.rfind('\\'); last_backslash != std::string::npos)
						kern.image_path = std::pair{path.substr(0, last_backslash + 1), path.substr(last_backslash + 1)};


@@ 111,22 112,27 @@ klapki::context::context klapki::context::context::derive(state::state & output_
			unsigned char * opt_data;
			size_t opt_data_len;
			efi_loadopt_optional_data(efi_opt, efi_opt_len, &opt_data, &opt_data_len);
			detail::tokenise_cmdline({reinterpret_cast<char *>(opt_data), opt_data_len}, [&](auto && arg) {
				if(!arg.compare(0, std::strlen("initrd="), "initrd=")) {
					auto initrd_path = arg.substr(std::strlen("initrd="));
					if(const auto last_backslash = initrd_path.rfind('\\'); last_backslash != std::string::npos)
						kern.initrd_paths.emplace_back(initrd_path.substr(0, last_backslash + 1), initrd_path.substr(last_backslash + 1));
			const std::unique_ptr<char[], free_deleter> opt_data_c{
			    reinterpret_cast<char *>(ucs2_to_utf8(reinterpret_cast<const char16_t *>(opt_data), opt_data_len))};
			detail::tokenise_cmdline(opt_data_c.get(), [&](auto && arg) {
				if(arg.substr(0, std::strlen("initrd=")) == "initrd=") {  // string_view::starts_with() is C++20
					if(kern.initrd_paths.size() == went.initrd_dirnames.size())
						fmt::print(stderr, "Entry {:04X}: added by cmdline: {}\n", went.bootnum_hint, arg);
					else {
						fmt::print(stderr, "Entry {:04X}: initrd={}: no backslashes? Relating to root.\n", went.bootnum_hint, initrd_path);
						kern.initrd_paths.emplace_back("\\", initrd_path);
						auto initrd_path = arg.substr(std::strlen("initrd="));
						if(const auto last_backslash = initrd_path.rfind('\\'); last_backslash != std::string::npos)
							kern.initrd_paths.emplace_back(initrd_path.substr(0, last_backslash + 1), initrd_path.substr(last_backslash + 1));
						else {
							fmt::print(stderr, "Entry {:04X}: initrd={}: no backslashes? Relating to root.\n", went.bootnum_hint, initrd_path);
							kern.initrd_paths.emplace_back("\\", initrd_path);
						}
					}

				} else {
					// TODO: this might mangle ws
					kern.cmdline += arg;
					kern.cmdline += ' ';
				}

				// TODO: this might mangle ws
				kern.cmdline += arg;
				kern.cmdline += ' ';

				return true;
			});
			if(!kern.cmdline.empty())

M src/context_save.cpp => src/context_save.cpp +17 -15
@@ 79,32 79,34 @@ std::optional<std::string> klapki::context::context::save(const config & cfg, st
			else if(errno != ENOSPC)
				return fmt::format("Making device path for {:04X}: {}", bootnum, strerror(errno));
		} while(errno == ENOSPC);
		if(cfg.verbose) {
			const auto size = efidp_format_device_path(nullptr, 0, reinterpret_cast<const efidp_data *>(devpath.data()), devpath.size());
			fmt::print("Entry {:04X} devpath: ", bootnum);
			if(size < 0)
				fmt::print("couldn't format?\n");
			else {
				std::string path(size, '\0');
				efidp_format_device_path(path.data(), path.size(), reinterpret_cast<const efidp_data *>(devpath.data()), devpath.size());
				fmt::print("{}\n", path);
			}
		}


		// TODO: put at end instead maybe?
		// Must be at start, we use position in derive() to match extraneous ones from cmdline
		std::string templine{};
		std::string_view prev = kern.image_path.first;
		for(auto && ipath : kern.initrd_paths) {
			templine += "initrd=";
			if(ipath.first)
				prev = *ipath.first;
			templine += prev;
			if(prev.back() != '\\' && ipath.second.front() != '\\')
				templine += '\\';
			templine += ipath.second;
			templine += ' ';
			fmt::format_to(std::back_inserter(templine), "initrd={}{}{} ", prev, (prev.back() == '\\' || ipath.second.front() == '\\') ? "" : "\\", ipath.second);
		}
		templine += kern.cmdline;
		fmt::print("templine={}\n", templine);
		if(cfg.verbose)
			fmt::print("Entry {:04X} cmdline: {}\n", bootnum, templine);

		std::vector<std::uint16_t> cmdline(utf8len(reinterpret_cast<std::uint8_t *>(templine.data()), templine.size()));
		fmt::print("cmdline.size()={}\n", cmdline.size());
		if(utf8_to_ucs2(cmdline.data(), cmdline.size() * sizeof(std::uint16_t), false, reinterpret_cast<std::uint8_t *>(templine.data())) < 0)
			return fmt::format("formatting cmdline: {}", strerror(errno));
		fmt::print("cmdline=");
		for(int i = 0; i < cmdline.size() * sizeof(std::uint16_t); ++i)
			fmt::print("{:02X}", reinterpret_cast<std::uint8_t *>(cmdline.data())[i]);
		fmt::print("\n");
			return fmt::format("Entry {:04X}: UCS-2ing cmdline: {}", bootnum, strerror(errno));

		// extern ssize_t efi_loadopt_create(uint8_t *buf, ssize_t size,
		//				  uint32_t attributes, efidp dp,


@@ 128,7 130,7 @@ std::optional<std::string> klapki::context::context::save(const config & cfg, st
		// write(open("oot", O_WRONLY | O_CREAT | O_DSYNC | O_TRUNC), bent->second.load_option.get(), bent->second.load_option_len);

		SHA1(bent->second.load_option.get(), bent->second.load_option_len, bent->second.load_option_sha);
		if(!std::memcmp(bent->second.load_option_sha, skern->load_option_sha, sizeof(sha_t)))
		if(std::memcmp(bent->second.load_option_sha, skern->load_option_sha, sizeof(sha_t)))
			fmt::print("Entry {:04X} changed\n", bootnum);
		std::memcpy(skern->load_option_sha, bent->second.load_option_sha, sizeof(sha_t));
	}

M src/context_wisen.cpp => src/context_wisen.cpp +1 -1
@@ 96,7 96,7 @@ namespace {

	static void validate_cmdline(const std::string_view & cmdline) {
		klapki::context::detail::tokenise_cmdline(cmdline, [&](auto && arg) {
			if(!arg.compare(0, std::strlen("initrd="), "initrd=")) {
			if(arg.substr(0, std::strlen("initrd=")) == "initrd=") {  // string_view::starts_with() is C++20
				fmt::print(stderr, "Stray {} in cmdline, things might not work as planned\n", arg);
				return false;
			} else

M src/main.cpp => src/main.cpp +4 -4
@@ 37,10 37,10 @@
		std::move(std::get<0>(ret));                               \
	})

#define TRY_OPT(ec, pref, ...)                         \
	if(auto err = __VA_ARGS__; err) { \
		fmt::print("{}: {}\n", pref, *err);                \
		return ec;                                         \
#define TRY_OPT(ec, pref, ...)          \
	if(auto err = __VA_ARGS__; err) {     \
		fmt::print("{}: {}\n", pref, *err); \
		return ec;                          \
	}



M src/state_commit.cpp => src/state_commit.cpp +1 -1
@@ 66,7 66,7 @@ std::optional<std::string> klapki::state::state::commit(const config & cfg, cons
		                       return std::nullopt;
	                       },
	                       [&](const auto & a, const auto & b) -> std::optional<std::string> {
		                       fmt::print("{}  {}\n", typeid(a).name(), typeid(b).name());
		                       fmt::print(stderr, "{}  {}\n", typeid(a).name(), typeid(b).name());
		                       throw __func__;
	                       },  // nothing can be done now. context::save() should've set this, and the original state is also flat
	                   },