From 88c531af14a144058edbde79d3193eb6fa1c212a Mon Sep 17 00:00:00 2001 From: Vladislav Nepogodin Date: Thu, 2 Dec 2021 14:52:18 +0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7=20update=20devices=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tui.cpp | 17 +++++++++++++---- src/utils.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++----- src/utils.hpp | 2 ++ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/tui.cpp b/src/tui.cpp index 7259b01..bdecf4c 100644 --- a/src/tui.cpp +++ b/src/tui.cpp @@ -3,6 +3,7 @@ #include "utils.hpp" /* clang-format off */ +#include // for transform #include // for __shared_ptr_access #include // for basic_string #include // for ftxui @@ -35,10 +36,18 @@ ftxui::Element centered_widget(ftxui::Component& container, const std::string_vi }); } +ftxui::Element multiline_text(const std::vector& lines) { + Elements multiline; + + std::transform(lines.cbegin(), lines.cend(), std::back_inserter(multiline), + [=](const std::string& line) -> Element { return text(line); }); + return vbox(std::move(multiline)) | frame; +} + // Simple code to show devices / partitions. -void show_devices() { - auto screen = ScreenInteractive::Fullscreen(); - const auto& lsblk = utils::exec("lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep \"disk\\|part\\|lvm\\|crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\\|MOUNTPOINT\""); +void show_devices() noexcept { + auto screen = ScreenInteractive::Fullscreen(); + auto lsblk = utils::exec("lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep \"disk\\|part\\|lvm\\|crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\\|MOUNTPOINT\""); /* clang-format off */ auto button_option = ButtonOption(); @@ -51,7 +60,7 @@ void show_devices() { }); auto renderer = Renderer(container, [&] { - return tui::centered_widget(container, "New CLI Installer", text(lsblk.data()) | size(HEIGHT, GREATER_THAN, 5)); + return tui::centered_widget(container, "New CLI Installer", multiline_text(utils::make_multiline(lsblk)) | size(HEIGHT, GREATER_THAN, 5)); }); screen.Loop(renderer); diff --git a/src/utils.cpp b/src/utils.cpp index e2d5c80..9f504ce 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,5 +1,6 @@ #include "utils.hpp" #include "config.hpp" +#include "definitions.hpp" #include // for array #include // for filesystem, seconds @@ -39,7 +40,7 @@ bool is_connected() noexcept { bool check_root() noexcept { #ifdef NDEVENV - return (utils::exec("whoami") == "root\n"); + return (utils::exec("whoami") == "root"); #else return true; #endif @@ -79,6 +80,10 @@ std::string exec(const std::string_view& command, bool capture_output) noexcept } } + if (result.ends_with('\n')) { + result.pop_back(); + } + pclose(pipe); return result; @@ -105,13 +110,48 @@ bool prompt_char(const char* prompt, const char* color, char* read) noexcept { return false; } +auto make_multiline(std::string& str) noexcept -> std::vector { + static constexpr std::string_view delim{"\n"}; + std::vector lines{}; + + std::size_t start{}; + std::size_t end = str.find(delim); + while (end != std::string::npos) { + lines.push_back(str.substr(start, end - start)); + start = end + delim.size(); + end = str.find(delim, start); + } + lines.push_back(str.substr(start, end - start)); + + return lines; +} + +// Unmount partitions. +void umount_partitions() noexcept { + auto* config_instance = Config::instance(); + auto& config_data = config_instance->data(); + auto mount_info = utils::exec(fmt::format("mount | grep \"{}\" | {}", config_data["MOUNTPOINT"], "awk \'{print $3}\' | sort -r")); +#ifdef NDEVENV + utils::exec("swapoff -a"); +#endif + + const auto& lines = utils::make_multiline(mount_info); + for (const auto& line : lines) { +#ifdef NDEVENV + umount(line.c_str()); +#else + output("{}\n", line); +#endif + } +} + void id_system() noexcept { auto* config_instance = Config::instance(); auto& config_data = config_instance->data(); // Apple System Detection const auto& sys_vendor = utils::exec("cat /sys/class/dmi/id/sys_vendor"); - if ((sys_vendor == "Apple Inc.\n") || (sys_vendor == "Apple Computer, Inc.\n")) + if ((sys_vendor == "Apple Inc.") || (sys_vendor == "Apple Computer, Inc.")) utils::exec("modprobe -r -q efivars || true"); // if MAC else utils::exec("modprobe -q efivarfs"); // all others @@ -121,7 +161,7 @@ void id_system() noexcept { if (fs::exists(efi_path) && fs::is_directory(efi_path)) { // Mount efivarfs if it is not already mounted const auto& mount_out = utils::exec("mount | grep /sys/firmware/efi/efivars"); - if (mount_out == "\n") { + if (mount_out.empty()) { if (mount("efivarfs", "/sys/firmware/efi/efivars", "efivarfs", 0, "") != 0) { perror("utils::id_system"); exit(1); @@ -132,11 +172,11 @@ void id_system() noexcept { // init system const auto& init_sys = utils::exec("cat /proc/1/comm"); - if (init_sys == "systemd\n") + if (init_sys == "systemd") config_data["H_INIT"] = "systemd"; // TODO: Test which nw-client is available, including if the service according to $H_INIT is running - if (config_data["H_INIT"] == "systemd" && utils::exec("systemctl is-active NetworkManager") == "active\n") + if (config_data["H_INIT"] == "systemd" && utils::exec("systemctl is-active NetworkManager") == "active") config_data["NW_CMD"] = "nmtui"; } diff --git a/src/utils.hpp b/src/utils.hpp index 19ee057..5ce0975 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -5,12 +5,14 @@ #include // for string #include // for string_view +#include // for vector namespace utils { void print_banner() noexcept; [[nodiscard]] bool is_connected() noexcept; bool prompt_char(const char* prompt, const char* color = RESET, char* read = nullptr) noexcept; void clear_screen() noexcept; +[[nodiscard]] auto make_multiline(std::string& str) noexcept -> std::vector; auto exec(const std::string_view& command, bool capture_output = true) noexcept -> std::string; [[nodiscard]] bool check_root() noexcept;