From 63dbfe3fc8b7fd2a886791702d2d60bcafa490cb Mon Sep 17 00:00:00 2001 From: LoveSy Date: Tue, 20 Jun 2023 21:41:20 +0800 Subject: [PATCH] Replace clap with argh Clap is too huge, see #clap-rs/clap#1365 --- native/src/Cargo.lock | 137 +++---------------- native/src/Cargo.toml | 2 +- native/src/boot/Cargo.toml | 2 +- native/src/boot/cpio.rs | 266 +++++++++++++++++++++++++++---------- native/src/boot/main.cpp | 27 +--- 5 files changed, 220 insertions(+), 214 deletions(-) diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index 92553a8fec579..65ebf86f3209e 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -12,59 +12,38 @@ dependencies = [ ] [[package]] -name = "anstream" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is-terminal", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" - -[[package]] -name = "anstyle-parse" -version = "0.2.0" +name = "anyhow" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" -dependencies = [ - "utf8parse", -] +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] -name = "anstyle-query" -version = "1.0.0" +name = "argh" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e" dependencies = [ - "windows-sys", + "argh_derive", + "argh_shared", ] [[package]] -name = "anstyle-wincon" -version = "1.0.1" +name = "argh_derive" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6" dependencies = [ - "anstyle", - "windows-sys", + "argh_shared", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "anyhow" -version = "1.0.71" +name = "argh_shared" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f" [[package]] name = "autocfg" @@ -108,48 +87,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "4.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" -dependencies = [ - "clap_builder", - "clap_derive", - "once_cell", -] - -[[package]] -name = "clap_builder" -version = "4.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" -dependencies = [ - "anstream", - "anstyle", - "bitflags", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "clap_lex" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" - [[package]] name = "codespan-reporting" version = "0.11.1" @@ -160,12 +97,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "cxx" version = "1.0.94" @@ -240,12 +171,6 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "hermit-abi" version = "0.3.1" @@ -282,18 +207,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys", -] - [[package]] name = "libc" version = "0.2.146" @@ -328,9 +241,9 @@ name = "magiskboot" version = "0.0.0" dependencies = [ "anyhow", + "argh", "base", "byteorder", - "clap", "cxx", "cxx-gen", "protobuf", @@ -505,12 +418,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fed904c7fb2856d868b92464fc8fa597fce366edea1a9cbfaa8cb5fe080bd6d" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "syn" version = "1.0.109" @@ -588,12 +495,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "which" version = "4.4.0" diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index 680f903831939..32736096aba53 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -16,7 +16,7 @@ protobuf = "3.2.0" protobuf-codegen = "3.2.0" byteorder = "1" size = "0.4" -clap = "4.3" +argh = "0.1.10" [profile.dev] opt-level = "z" diff --git a/native/src/boot/Cargo.toml b/native/src/boot/Cargo.toml index edfda90796be9..7d7a60a04a65f 100644 --- a/native/src/boot/Cargo.toml +++ b/native/src/boot/Cargo.toml @@ -17,5 +17,5 @@ cxx = { path = "../external/cxx-rs" } protobuf = { workspace = true } byteorder = { workspace = true } anyhow = { workspace = true } -clap = { workspace = true, features = ["derive"] } size = { workspace = true } +argh = { workspace = true } diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index d04dea889889d..8fff1fd16c06a 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -1,3 +1,4 @@ +use argh::{EarlyExit, FromArgs}; use std::collections::BTreeMap; use std::ffi::CStr; use std::fmt::{Display, Formatter}; @@ -10,7 +11,6 @@ use std::process::exit; use std::slice; use anyhow::{anyhow, Context}; -use clap::{Parser, Subcommand}; use size::{Base, Size, Style}; use base::libc::{ @@ -22,57 +22,161 @@ use base::{MappedFile, ResultExt, StrErr, Utf8CStr, WriteExt}; use crate::ramdisk::MagiskCpio; -#[derive(Parser)] +#[derive(FromArgs)] +#[argh(description = "Manipulate cpio archives; --help for more info.")] struct CpioCli { - #[command(subcommand)] + #[argh(subcommand)] command: CpioCommands, } -#[derive(Subcommand)] +#[derive(FromArgs)] +#[argh(subcommand)] enum CpioCommands { - Test {}, - Restore {}, - Patch {}, - Exists { - path: String, - }, - Backup { - origin: String, - }, - Rm { - path: String, - #[arg(short)] - recursive: bool, - }, - Mv { - from: String, - to: String, - }, - Extract { - #[arg(requires("out"))] - path: Option, - out: Option, - }, - Mkdir { - #[arg(value_parser=parse_mode)] - mode: mode_t, - dir: String, - }, - Ln { - src: String, - dst: String, - }, - Add { - #[arg(value_parser=parse_mode)] - mode: mode_t, - path: String, - file: String, - }, - Ls { - path: Option, - #[arg(short)] - recursive: bool, - }, + Test(Test), + Restore(Restore), + Patch(Patch), + Exists(Exists), + Backup(Backup), + Remove(Remove), + Move(Move), + Extract(Extract), + MakeDir(MakeDir), + Link(Link), + Add(Add), + List(List), +} + +#[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" +)] +struct Test {} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "restore", + description = "Restore ramdisk from ramdisk backup stored within incpio" +)] +struct Restore {} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "patch", + description = "Apply ramdisk patches; configure with env variables: KEEPVERITY KEEPFORCEENCRYPT" +)] +struct Patch {} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "exists", + description = "Return 0 if exists, otherwise return 1" +)] +struct Exists { + #[argh(positional, arg_name = "entry")] + path: String, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "backup", + description = "Create ramdisk backups from " +)] +struct Backup { + #[argh(positional, arg_name = "orig")] + origin: String, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "rm", + description = "Remove ; specify [-r] to remove recursively" +)] +struct Remove { + #[argh(positional, arg_name = "entry")] + path: String, + #[argh(switch, short = 'r', description = "recursive")] + recursive: bool, +} + +#[derive(FromArgs)] +#[argh(subcommand, name = "mv", description = "Move to ")] +struct Move { + #[argh(positional, arg_name = "source")] + from: String, + #[argh(positional, arg_name = "dest")] + to: String, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "extract", + description = "Extract to , or extract all entries to current directory if is not given" +)] +struct Extract { + #[argh(positional, greedy)] + paths: Vec, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "mkdir", + description = "Create directory in permissions (in octal)" +)] +struct MakeDir { + #[argh(positional, from_str_fn(parse_mode))] + mode: mode_t, + #[argh(positional, arg_name = "entry")] + dir: String, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "ln", + description = "Create a symlink to with the name " +)] +struct Link { + #[argh(positional, arg_name = "entry")] + src: String, + #[argh(positional, arg_name = "target")] + dst: String, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "add", + description = "Add as in permissions (in octal); replace if exists" +)] +struct Add { + #[argh(positional, from_str_fn(parse_mode))] + mode: mode_t, + #[argh(positional, arg_name = "entry")] + path: String, + #[argh(positional, arg_name = "infile")] + file: String, +} + +#[derive(FromArgs)] +#[argh( + subcommand, + name = "ls", + description = r#"List [] ("/" by default); specifly [-r] to recursively list sub-directories"# +)] +struct List { + #[argh(positional, default = r#"String::from("/")"#)] + path: String, + #[argh(switch, short = 'r', description = "recursive")] + recursive: bool, } #[repr(C, packed)] @@ -233,6 +337,7 @@ impl Cpio { S_IFDIR => { DirBuilder::new() .mode((entry.mode & 0o777).into()) + .recursive(true) // avoid error if existing .create(out)?; } S_IFREG => { @@ -356,11 +461,16 @@ impl Cpio { Ok(()) } - fn ls(&self, path: Option<&str>, recursive: bool) { - let path = path - .map(norm_path) - .filter(|p| !p.is_empty()) - .map_or("".to_string(), |p| "/".to_string() + p.as_str()); + fn ls(&self, path: &str, recursive: bool) { + let path = match norm_path(path) { + path => { + if path.is_empty() { + path + } else { + "/".to_string() + path.as_str() + } + } + }; for (name, entry) in &self.entries { let p = "/".to_string() + name.as_str(); if !p.starts_with(&path) { @@ -436,32 +546,52 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { if cmd.starts_with('#') { continue; } - let cmd = "magiskboot ".to_string() + cmd; - let mut cli = CpioCli::try_parse_from(cmd.split(' ').filter(|x| !x.is_empty()))?; + let mut cli = match CpioCli::from_args( + &["magiskboot", "cpio", &*file], + cmd.split(' ') + .filter(|x| !x.is_empty()) + .collect::>() + .as_slice(), + ) { + Ok(cli) => cli, + Err(EarlyExit { output, status }) => match status { + Ok(_) => { + eprintln!("{}", output); + exit(0) + } + Err(_) => return Err(anyhow!(output)), + }, + }; match &mut cli.command { - CpioCommands::Test {} => exit(cpio.test()), - CpioCommands::Restore {} => cpio.restore()?, - CpioCommands::Patch {} => cpio.patch(), - CpioCommands::Exists { path } => { + CpioCommands::Test(Test {}) => exit(cpio.test()), + CpioCommands::Restore(Restore {}) => cpio.restore()?, + CpioCommands::Patch(Patch {}) => cpio.patch(), + CpioCommands::Exists(Exists { path }) => { if cpio.exists(path) { exit(0); } else { exit(1); } } - CpioCommands::Backup { ref mut origin } => { + CpioCommands::Backup(Backup { origin }) => { cpio.backup(Utf8CStr::from_string(origin))? } - CpioCommands::Rm { path, recursive } => cpio.rm(path, *recursive), - CpioCommands::Mv { from, to } => cpio.mv(from, to)?, - CpioCommands::Extract { path, out } => { - cpio.extract(path.as_deref(), out.as_deref())? + CpioCommands::Remove(Remove { path, recursive }) => cpio.rm(path, *recursive), + CpioCommands::Move(Move { from, to }) => cpio.mv(from, to)?, + CpioCommands::MakeDir(MakeDir { mode, dir }) => cpio.mkdir(mode, dir), + CpioCommands::Link(Link { src, dst }) => cpio.ln(src, dst), + CpioCommands::Add(Add { mode, path, file }) => cpio.add(mode, path, file)?, + CpioCommands::Extract(Extract { paths }) => { + if paths.len() != 0 && paths.len() != 2 { + return Err(anyhow!("invalid arguments")); + } + cpio.extract( + paths.get(0).map(|x| x.as_str()), + paths.get(1).map(|x| x.as_str()), + )?; } - CpioCommands::Mkdir { mode, dir } => cpio.mkdir(mode, dir), - CpioCommands::Ln { src, dst } => cpio.ln(src, dst), - CpioCommands::Add { mode, path, file } => cpio.add(mode, path, file)?, - CpioCommands::Ls { path, recursive } => { - cpio.ls(path.as_deref(), *recursive); + CpioCommands::List(List { path, recursive }) => { + cpio.ls(path.as_str(), *recursive); exit(0); } } diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index 6465b74f301f5..f06214736057c 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -60,32 +60,7 @@ Supported actions: 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 - rm [-r] ENTRY - Remove ENTRY, specify [-r] to remove recursively - mkdir MODE ENTRY - Create directory ENTRY in 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 in 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 + See "cpio --help" for supported commands. dtb [args...] Do dtb related actions to