Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEXRootFSFetcher: Fallback to TTY if zenity isn't installed #4063

Merged
merged 2 commits into from
Sep 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 44 additions & 22 deletions Source/Tools/FEXRootFSFetcher/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,15 @@ namespace WorkingAppsTester {
static bool Has_Curl {false};
static bool Has_Squashfuse {false};
static bool Has_Unsquashfs {false};
static bool Has_Zenity {false};

// EroFS specific
static bool Has_EroFSFuse {false};
static bool Has_EroFSFsck {false};

void CheckCurl() {
// Check if curl exists on the host
std::vector<const char*> ExecveArgs = {
const std::array<const char*, 3> ExecveArgs = {
"curl",
"-V",
nullptr,
Expand All @@ -230,7 +231,7 @@ void CheckCurl() {
}

void CheckSquashfuse() {
std::vector<const char*> ExecveArgs = {
const std::array<const char*, 3> ExecveArgs = {
"squashfuse",
"--help",
nullptr,
Expand All @@ -241,7 +242,7 @@ void CheckSquashfuse() {
}

void CheckUnsquashfs() {
std::vector<const char*> ExecveArgs = {
const std::array<const char*, 3> ExecveArgs = {
"unsquashfs",
"--help",
nullptr,
Expand Down Expand Up @@ -284,10 +285,21 @@ void CheckUnsquashfs() {
}
close(fd);
}
void CheckZenity() {
// Check if zenity exists on the host
std::array<const char*, 3> ExecveArgs = {
"zenity",
"-h",
nullptr,
};

int32_t Result = Exec::ExecAndWaitForResponseRedirect(ExecveArgs[0], const_cast<char* const*>(ExecveArgs.data()), -1, -1);
Has_Zenity = Result != -1;
}

// EroFS specific tests
void CheckEroFSFuse() {
std::vector<const char*> ExecveArgs = {
std::array<const char*, 3> ExecveArgs = {
"erofsfuse",
"--help",
nullptr,
Expand All @@ -298,7 +310,7 @@ void CheckEroFSFuse() {
}

void CheckEroFSFsck() {
std::vector<const char*> ExecveArgs = {
std::array<const char*, 3> ExecveArgs = {
"fsck.erofs",
"-V",
nullptr,
Expand All @@ -312,6 +324,7 @@ void Init() {
CheckCurl();
CheckSquashfuse();
CheckUnsquashfs();
CheckZenity();
CheckEroFSFuse();
CheckEroFSFsck();
}
Expand Down Expand Up @@ -486,7 +499,7 @@ struct FileTargets {
const static std::string DownloadURL = "https://rootfs.fex-emu.gg/RootFS_links.json";

std::string DownloadToString(const std::string& URL) {
std::vector<const char*> ExecveArgs = {
std::array<const char*, 3> ExecveArgs = {
"curl",
URL.c_str(),
nullptr,
Expand All @@ -499,7 +512,7 @@ bool DownloadToPath(const fextl::string& URL, const fextl::string& Path) {
auto filename = URL.substr(URL.find_last_of('/') + 1);
auto PathName = Path + filename;

std::vector<const char*> ExecveArgs = {
std::array<const char*, 5> ExecveArgs = {
"curl", URL.c_str(), "-o", PathName.c_str(), nullptr,
};

Expand All @@ -520,7 +533,7 @@ bool DownloadToPathWithZenityProgress(const fextl::string& URL, const fextl::str
// Making zenity vanish immediately
const std::string ZenityBuf = "zenity --time-remaining --progress --no-cancel --title 'Downloading'";
std::string BigArgs = fmt::format("{} | {} | {} | {}", CurlPipe, StdBuf, SedBuf, ZenityBuf);
std::vector<const char*> ExecveArgs = {
std::array<const char*, 4> ExecveArgs = {
"/bin/sh",
"-c",
BigArgs.c_str(),
Expand Down Expand Up @@ -627,7 +640,7 @@ bool AskForConfirmation(const fextl::string& Question) {
return ArgOptions::AssumeYes || ExecWithQuestion(Question);
}

int32_t AskForConfirmationList(const fextl::string& Text, const std::vector<fextl::string>& Arguments) {
int32_t AskForConfirmationList(const fextl::string& Text, const std::span<const fextl::string> Arguments) {
fextl::string TextArg = "--text=" + Text;

std::vector<const char*> ExecveArgs = {
Expand All @@ -653,7 +666,7 @@ int32_t AskForConfirmationList(const fextl::string& Text, const std::vector<fext
return std::stoi(Result);
}

int32_t AskForComplexConfirmationList(const std::string& Text, const std::vector<std::string>& Arguments) {
int32_t AskForComplexConfirmationList(const std::string& Text, const std::span<const std::string> Arguments) {
std::string TextArg = "--text=" + Text;

std::vector<const char*> ExecveArgs = {
Expand All @@ -674,7 +687,7 @@ int32_t AskForComplexConfirmationList(const std::string& Text, const std::vector
return std::stoi(Result);
}

int32_t AskForDistroSelection(DistroQuery::DistroInfo& Info, std::vector<WebFileFetcher::FileTargets>& Targets) {
int32_t AskForDistroSelection(DistroQuery::DistroInfo& Info, const std::span<const WebFileFetcher::FileTargets> Targets) {
// Search for an exact match
int32_t DistroIndex = -1;
if (!Info.Unknown) {
Expand Down Expand Up @@ -724,7 +737,7 @@ bool ValidateCheckExists(const WebFileFetcher::FileTargets& Target) {

std::error_code ec;
if (std::filesystem::exists(PathName, ec)) {
const std::vector<fextl::string> Args {
const std::array<const fextl::string, 2> Args {
"Overwrite",
"Validate",
};
Expand Down Expand Up @@ -813,7 +826,7 @@ void ExecWithInfo(const fextl::string& Text) {
std::cout << Text << std::endl;
}

int32_t AskForConfirmationList(const fextl::string& Text, const std::vector<fextl::string>& List) {
int32_t AskForConfirmationList(const fextl::string& Text, std::span<const fextl::string> List) {
fmt::print("{}\n", Text);
fmt::print("Options:\n");
fmt::print("\t0: Cancel\n");
Expand All @@ -837,7 +850,7 @@ int32_t AskForConfirmationList(const fextl::string& Text, const std::vector<fext
}
}

int32_t AskForDistroSelection(DistroQuery::DistroInfo& Info, std::vector<WebFileFetcher::FileTargets>& Targets) {
int32_t AskForDistroSelection(DistroQuery::DistroInfo& Info, const std::span<const WebFileFetcher::FileTargets> Targets) {
// Search for an exact match
int32_t DistroIndex = -1;
if (!Info.Unknown) {
Expand Down Expand Up @@ -882,7 +895,7 @@ bool ValidateCheckExists(const WebFileFetcher::FileTargets& Target) {

std::error_code ec;
if (std::filesystem::exists(PathName, ec)) {
const std::vector<fextl::string> Args {
const std::array<fextl::string, 2> Args {
"Overwrite",
"Validate",
};
Expand Down Expand Up @@ -954,8 +967,8 @@ bool ValidateDownloadSelection(const WebFileFetcher::FileTargets& Target) {
namespace {
std::function<bool(const fextl::string& Question)> _AskForConfirmation;
std::function<void(const fextl::string& Text)> _ExecWithInfo;
std::function<int32_t(const fextl::string& Text, const std::vector<fextl::string>& List)> _AskForConfirmationList;
std::function<int32_t(DistroQuery::DistroInfo& Info, std::vector<WebFileFetcher::FileTargets>& Targets)> _AskForDistroSelection;
std::function<int32_t(const fextl::string& Text, const std::span<const fextl::string> List)> _AskForConfirmationList;
std::function<int32_t(DistroQuery::DistroInfo& Info, const std::span<const WebFileFetcher::FileTargets> Targets)> _AskForDistroSelection;
std::function<bool(const WebFileFetcher::FileTargets& Target)> _ValidateCheckExists;
std::function<bool(const WebFileFetcher::FileTargets& Target)> _ValidateDownloadSelection;

Expand All @@ -967,6 +980,14 @@ void CheckTTY() {
IsTTY = ArgOptions::UIOption == ArgOptions::UIOverrideOption::TTY;
}

if (!WorkingAppsTester::Has_Zenity) {
// Force TTY if zenity isn't installed.
if (ArgOptions::UIOption == ArgOptions::UIOverrideOption::Zenity) {
fmt::print("Zenity isn't executable. Falling back to TTY mode\n");
}
IsTTY = true;
}

if (IsTTY) {
_AskForConfirmation = TTY::AskForConfirmation;
_ExecWithInfo = TTY::ExecWithInfo;
Expand All @@ -992,11 +1013,11 @@ void ExecWithInfo(const fextl::string& Text) {
_ExecWithInfo(Text);
}

int32_t AskForConfirmationList(const fextl::string& Text, const std::vector<fextl::string>& Arguments) {
int32_t AskForConfirmationList(const fextl::string& Text, const std::span<const fextl::string> Arguments) {
return _AskForConfirmationList(Text, Arguments);
}

int32_t AskForDistroSelection(std::vector<WebFileFetcher::FileTargets>& Targets) {
int32_t AskForDistroSelection(const std::span<const WebFileFetcher::FileTargets> Targets) {
auto Info = DistroQuery::GetDistroInfo();

if (!ArgOptions::DistroName.empty()) {
Expand Down Expand Up @@ -1045,7 +1066,7 @@ bool UnsquashRootFS(const fextl::string& Path, const fextl::string& RootFS, cons
}
}

const std::vector<const char*> ExecveArgs = {
const std::array<const char*, 6> ExecveArgs = {
"unsquashfs", "-f", "-d", TargetFolder.c_str(), RootFS.c_str(), nullptr,
};

Expand All @@ -1071,7 +1092,7 @@ bool ExtractEroFS(const fextl::string& Path, const fextl::string& RootFS, const
ExecWithInfo("Extracting Erofs. This might take a few minutes.");

const auto ExtractOption = fmt::format("--extract={}", TargetFolder);
const std::vector<const char*> ExecveArgs = {
const std::array<const char*, 4> ExecveArgs = {
"fsck.erofs",
ExtractOption.c_str(),
RootFS.c_str(),
Expand All @@ -1091,6 +1112,8 @@ int main(int argc, char** argv, char** const envp) {

ArgOptions::ParseArguments(argc, argv);

WorkingAppsTester::Init();

CheckTTY();

if (ArgOptions::RemainingArgs.size()) {
Expand All @@ -1103,7 +1126,6 @@ int main(int argc, char** argv, char** const envp) {
return 0;
}

WorkingAppsTester::Init();
// Check if curl exists on the host
if (!WorkingAppsTester::Has_Curl) {
ExecWithInfo("curl is required to use this tool. Please install curl before using.");
Expand Down
Loading