From d778b0b0a704f1bbfb1b76e04a84174383be9285 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 5 Jul 2023 17:05:39 -0700 Subject: [PATCH] Custom help message when using argh Help messages generated from argh is nearly useless and very hard to customize. Fork argh and disable all code for generating help messages. Use a closure to print the help message when handling EarlyExit. --- .gitmodules | 3 + native/src/Cargo.lock | 6 -- native/src/Cargo.toml | 2 +- native/src/base/misc.rs | 7 ++- native/src/boot/cpio.rs | 131 ++++++++++++++++++++------------------- native/src/boot/main.cpp | 6 +- native/src/external/argh | 1 + 7 files changed, 79 insertions(+), 77 deletions(-) create mode 160000 native/src/external/argh diff --git a/.gitmodules b/.gitmodules index e514a7f6d..042008edd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -46,3 +46,6 @@ [submodule "termux-elf-cleaner"] path = tools/termux-elf-cleaner url = https://github.com/termux/termux-elf-cleaner.git +[submodule "argh"] + path = native/src/external/argh + url = https://github.com/topjohnwu/argh.git diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index 5492d8257..dc4d5f1cd 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -23,8 +23,6 @@ dependencies = [ [[package]] name = "argh" version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e" dependencies = [ "argh_derive", "argh_shared", @@ -33,8 +31,6 @@ dependencies = [ [[package]] name = "argh_derive" version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6" dependencies = [ "argh_shared", "proc-macro2", @@ -45,8 +41,6 @@ dependencies = [ [[package]] name = "argh_shared" version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f" [[package]] name = "atty" diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index ce59eba12..ae64d5790 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -6,6 +6,7 @@ resolver = "2" [workspace.dependencies] cxx = { path = "external/cxx-rs" } cxx-gen = { path = "external/cxx-rs/gen/lib" } +argh = { path = "external/argh/argh" } libc = "0.2" cfg-if = "1.0" num-traits = "0.2" @@ -13,7 +14,6 @@ num-derive = "0.3" thiserror = "1.0" byteorder = "1" size = "0.4" -argh = "0.1.10" sha1 = "0.10" sha2 = "0.10" digest = "0.10" diff --git a/native/src/base/misc.rs b/native/src/base/misc.rs index 1a048f05a..4a529c6b6 100644 --- a/native/src/base/misc.rs +++ b/native/src/base/misc.rs @@ -382,20 +382,21 @@ pub fn map_args<'a>(argc: i32, argv: *const *const c_char) -> Result { - fn early_exit(self) -> T; + fn on_early_exit(self, print_help_msg: F) -> T; } impl EarlyExitExt for Result { - fn early_exit(self) -> T { + fn on_early_exit(self, print_help_msg: F) -> T { match self { Ok(t) => t, Err(EarlyExit { output, status }) => match status { Ok(_) => { - eprintln!("{}", output); + print_help_msg(); exit(0) } Err(_) => { eprintln!("{}", output); + print_help_msg(); exit(1) } }, diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index cf2402a9d..03008eb2c 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -23,7 +23,6 @@ use base::{ use crate::ramdisk::MagiskCpio; #[derive(FromArgs)] -#[argh(description = "Manipulate cpio archives; --help for more info.")] struct CpioCli { #[argh(subcommand)] command: CpioCommands, @@ -47,66 +46,42 @@ enum CpioCommands { } #[derive(FromArgs)] -#[argh( - subcommand, - name = "test", - description = "Test the cpio's status; return value is 0 or bitwise or-ed of following values: 0x1:Magisk; 0x2:unsupported; 0x4:Sony" -)] +#[argh(subcommand, name = "test")] struct Test {} #[derive(FromArgs)] -#[argh( - subcommand, - name = "restore", - description = "Restore ramdisk from ramdisk backup stored within incpio" -)] +#[argh(subcommand, name = "restore")] struct Restore {} #[derive(FromArgs)] -#[argh( - subcommand, - name = "patch", - description = "Apply ramdisk patches; configure with env variables: KEEPVERITY KEEPFORCEENCRYPT" -)] +#[argh(subcommand, name = "patch")] struct Patch {} #[derive(FromArgs)] -#[argh( - subcommand, - name = "exists", - description = "Return 0 if exists, otherwise return 1" -)] +#[argh(subcommand, name = "exists")] struct Exists { #[argh(positional, arg_name = "entry")] path: String, } #[derive(FromArgs)] -#[argh( - subcommand, - name = "backup", - description = "Create ramdisk backups from " -)] +#[argh(subcommand, name = "backup")] struct Backup { #[argh(positional, arg_name = "orig")] origin: String, } #[derive(FromArgs)] -#[argh( - subcommand, - name = "rm", - description = "Remove ; specify [-r] to remove recursively" -)] +#[argh(subcommand, name = "rm")] struct Remove { #[argh(positional, arg_name = "entry")] path: String, - #[argh(switch, short = 'r', description = "recursive")] + #[argh(switch, short = 'r')] recursive: bool, } #[derive(FromArgs)] -#[argh(subcommand, name = "mv", description = "Move to ")] +#[argh(subcommand, name = "mv")] struct Move { #[argh(positional, arg_name = "source")] from: String, @@ -115,22 +90,14 @@ struct Move { } #[derive(FromArgs)] -#[argh( - subcommand, - name = "extract", - description = "Extract to , or extract all entries to current directory if is not given" -)] +#[argh(subcommand, name = "extract")] struct Extract { #[argh(positional, greedy)] paths: Vec, } #[derive(FromArgs)] -#[argh( - subcommand, - name = "mkdir", - description = "Create directory in permissions (in octal)" -)] +#[argh(subcommand, name = "mkdir")] struct MakeDir { #[argh(positional, from_str_fn(parse_mode))] mode: mode_t, @@ -139,11 +106,7 @@ struct MakeDir { } #[derive(FromArgs)] -#[argh( - subcommand, - name = "ln", - description = "Create a symlink to with the name " -)] +#[argh(subcommand, name = "ln")] struct Link { #[argh(positional, arg_name = "entry")] src: String, @@ -152,11 +115,7 @@ struct Link { } #[derive(FromArgs)] -#[argh( - subcommand, - name = "add", - description = "Add as in permissions (in octal); replace if exists" -)] +#[argh(subcommand, name = "add")] struct Add { #[argh(positional, from_str_fn(parse_mode))] mode: mode_t, @@ -167,18 +126,53 @@ struct Add { } #[derive(FromArgs)] -#[argh( - subcommand, - name = "ls", - description = r#"List [] ("/" by default); specifly [-r] to recursively list sub-directories"# -)] +#[argh(subcommand, name = "ls")] struct List { #[argh(positional, default = r#"String::from("/")"#)] path: String, - #[argh(switch, short = 'r', description = "recursive")] + #[argh(switch, short = 'r')] recursive: bool, } +fn print_cpio_usage() { + eprintln!( + r#"Usage: magiskboot cpio [commands...] + +Do cpio commands to (modifications are done in-place). +Each command is a single argument; add quotes for each command. + +Supported commands: + exists ENTRY + Return 0 if ENTRY exists, else return 1 + ls [-r] [PATH] + List PATH ("/" by default); specify [-r] to list recursively + rm [-r] ENTRY + Remove ENTRY, specify [-r] to remove recursively + mkdir MODE ENTRY + Create directory ENTRY with permissions MODE + ln TARGET ENTRY + Create a symlink to TARGET with the name ENTRY + mv SOURCE DEST + Move SOURCE to DEST + add MODE ENTRY INFILE + Add INFILE as ENTRY with permissions MODE; replaces ENTRY if exists + extract [ENTRY OUT] + Extract ENTRY to OUT, or extract all entries to current directory + test + Test the cpio's status + Return value is 0 or bitwise or-ed of following values: + 0x1:Magisk 0x2:unsupported 0x4:Sony + patch + Apply ramdisk patches + Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT + backup ORIG + Create ramdisk backups from ORIG + restore + Restore ramdisk from ramdisk backup stored within incpio +"# + ) +} + #[repr(C, packed)] struct CpioHeader { magic: [u8; 6], @@ -523,11 +517,20 @@ impl Display for CpioEntry { pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { fn inner(argc: i32, argv: *const *const c_char) -> LoggedResult<()> { if argc < 1 { - return Err(log_err!("no arguments")); + return Err(log_err!("No arguments")); } let cmds = map_args(argc, argv)?; + if cmds[0] == "--help" { + print_cpio_usage(); + exit(0); + } + + if argc < 2 { + return Err(log_err!("No commands")); + } + let file = cmds[0]; let mut cpio = if Path::new(file).exists() { Cpio::load_from_file(file)? @@ -546,12 +549,12 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { .collect::>() .as_slice(), ) - .early_exit(); + .on_early_exit(print_cpio_usage); match &mut cli.command { - CpioCommands::Test(Test {}) => exit(cpio.test()), - CpioCommands::Restore(Restore {}) => cpio.restore()?, - CpioCommands::Patch(Patch {}) => cpio.patch(), + CpioCommands::Test(_) => exit(cpio.test()), + CpioCommands::Restore(_) => cpio.restore()?, + CpioCommands::Patch(_) => cpio.patch(), CpioCommands::Exists(Exists { path }) => { if cpio.exists(path) { exit(0); diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index f69a2f330..3d814dcb4 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -57,9 +57,9 @@ Supported actions: Search in , and replace it with cpio [commands...] - Do cpio commands to (modifications are done in-place) - Each command is a single argument, add quotes for each command. - See "cpio --help" for supported commands. + Do cpio commands to (modifications are done in-place). + Each command is a single argument; add quotes for each command. + See "cpio --help" for supported commands. dtb [args...] Do dtb related actions to diff --git a/native/src/external/argh b/native/src/external/argh new file mode 160000 index 000000000..2fecd81d6 --- /dev/null +++ b/native/src/external/argh @@ -0,0 +1 @@ +Subproject commit 2fecd81d606364a8b07b942ed01697bbd3a62193