Serenity Operating System
at master 111 lines 3.6 kB view raw
1/* 2 * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> 3 * Copyright (c) 2022, Tim Schumacher <timschumi@gmx.de> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <AK/LexicalPath.h> 9#include <LibMain/Main.h> 10#include <Userland/Shell/Shell.h> 11 12#define ENUMERATE_UTILITIES(E) \ 13 E(cat) \ 14 E(checksum) \ 15 E(chmod) \ 16 E(chown) \ 17 E(cp) \ 18 E(df) \ 19 E(env) \ 20 E(file) \ 21 E(find) \ 22 E(id) \ 23 E(less) \ 24 E(ln) \ 25 E(ls) \ 26 E(lsblk) \ 27 E(mkdir) \ 28 E(mknod) \ 29 E(mount) \ 30 E(mv) \ 31 E(ps) \ 32 E(rm) \ 33 E(sh) \ 34 E(rmdir) \ 35 E(tail) \ 36 E(tree) \ 37 E(umount) \ 38 E(uname) \ 39 E(uniq) 40 41// Declare the entrypoints of all the tools that we delegate to. 42// Relying on `decltype(serenity_main)` ensures that we always stay consistent with the `serenity_main` signature. 43#define DECLARE_ENTRYPOINT(name) decltype(serenity_main) name##_main; 44ENUMERATE_UTILITIES(DECLARE_ENTRYPOINT) 45#undef DECLARE_ENTRYPOINT 46 47static void fail() 48{ 49 out(stderr, "Direct running of BuggieBox was detected without finding a proper requested utility.\n"); 50 out(stderr, "The following programs are supported: uname, env, lsblk, file, df, mount, umount, mkdir, "); 51 out(stderr, "rmdir, rm, chown, chmod, cp, ln, ls, mv, cat, md5sum, sha1sum, sha256sum, sha512sum, sh, uniq, id, tail, "); 52 out(stderr, "find, less, mknod, ps\n"); 53 out(stderr, "To use one of these included utilities, create a symbolic link with the target being this binary, and ensure the basename"); 54 out(stderr, "is included within.\n"); 55} 56 57struct Runner { 58 StringView name; 59 ErrorOr<int> (*func)(Main::Arguments arguments) = nullptr; 60}; 61 62static constexpr Runner s_runners[] = { 63#define RUNNER_ENTRY(name) { #name##sv, name##_main }, 64 ENUMERATE_UTILITIES(RUNNER_ENTRY) 65#undef RUNNER_ENTRY 66 67 // Some tools have additional aliases. 68 { "md5sum"sv, checksum_main }, 69 { "sha1sum"sv, checksum_main }, 70 { "sha256sum"sv, checksum_main }, 71 { "sha512sum"sv, checksum_main }, 72 { "Shell"sv, sh_main }, 73}; 74 75static ErrorOr<int> run_program(Main::Arguments arguments, LexicalPath const& runbase, bool& found_runner) 76{ 77 for (auto& runner : s_runners) { 78 if (runbase.basename() == runner.name) { 79 found_runner = true; 80 return runner.func(arguments); 81 } 82 } 83 return 0; 84} 85 86static ErrorOr<int> buggiebox_main(Main::Arguments arguments) 87{ 88 if (arguments.argc == 0) { 89 fail(); 90 return 1; 91 } 92 bool found_runner = false; 93 LexicalPath runbase { arguments.strings[0] }; 94 auto result = TRY(run_program(arguments, runbase, found_runner)); 95 if (!found_runner) 96 fail(); 97 return result; 98} 99 100ErrorOr<int> serenity_main(Main::Arguments arguments) 101{ 102 LexicalPath runbase { arguments.strings[0] }; 103 if (runbase.basename() == "BuggieBox"sv) { 104 Main::Arguments utility_arguments = arguments; 105 utility_arguments.argc--; 106 utility_arguments.argv++; 107 utility_arguments.strings = arguments.strings.slice(1); 108 return buggiebox_main(utility_arguments); 109 } 110 return buggiebox_main(arguments); 111}