Replace clap with argh

This commit is contained in:
LoveSy 2023-06-20 21:41:20 +08:00 committed by John Wu
parent 732a161b67
commit 24b1c607f3
5 changed files with 233 additions and 357 deletions

293
native/src/Cargo.lock generated
View File

@ -20,68 +20,47 @@ dependencies = [
"winapi",
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "anyhow"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
[[package]]
name = "argh"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
dependencies = [
"argh_derive",
"argh_shared",
]
[[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",
"quote",
"syn 1.0.109",
]
[[package]]
name = "argh_shared"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"hermit-abi",
"libc",
"winapi",
]
@ -137,54 +116,12 @@ dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim 0.8.0",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "clap"
version = "4.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2686c4115cb0810d9a984776e197823d08ec94f176549a89a9efded477c456dc"
dependencies = [
"clap_builder",
"clap_derive",
"once_cell",
]
[[package]]
name = "clap_builder"
version = "4.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e53afce1efce6ed1f633cf0e57612fe51db54a1ee4fd8f8503d078fe02d69ae"
dependencies = [
"anstream",
"anstyle",
"bitflags",
"clap_lex",
"strsim 0.10.0",
]
[[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"
@ -195,12 +132,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"
@ -246,33 +177,6 @@ dependencies = [
"termcolor",
]
[[package]]
name = "errno"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[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.1.19"
@ -282,12 +186,6 @@ dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "humantime"
version = "1.3.0"
@ -297,41 +195,12 @@ dependencies = [
"quick-error",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"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 0.3.1",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "libc"
version = "0.2.146"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "log"
version = "0.4.19"
@ -354,9 +223,9 @@ name = "magiskboot"
version = "0.0.0"
dependencies = [
"anyhow",
"argh",
"base",
"byteorder",
"clap 4.3.5",
"cxx",
"cxx-gen",
"pb-rs",
@ -426,18 +295,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "pb-rs"
version = "0.10.0"
source = "git+https://github.com/tafia/quick-protobuf.git?rev=2f37d5a65504de7d716b5b28fd82219501a901a9#2f37d5a65504de7d716b5b28fd82219501a901a9"
dependencies = [
"clap 2.34.0",
"clap",
"env_logger",
"log",
"nom",
@ -492,20 +355,6 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]]
name = "rustix"
version = "0.37.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "size"
version = "0.4.1"
@ -518,12 +367,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[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"
@ -596,12 +439,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 = "vec_map"
version = "0.8.2"
@ -638,69 +475,3 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"

View File

@ -14,7 +14,7 @@ num-derive = "0.3"
thiserror = "1.0"
byteorder = "1"
size = "0.4"
clap = "4.3"
argh = "0.1.10"
pb-rs = { git = "https://github.com/tafia/quick-protobuf.git", rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" }
quick-protobuf = { git = "https://github.com/tafia/quick-protobuf.git", rev = "2f37d5a65504de7d716b5b28fd82219501a901a9" }

View File

@ -16,6 +16,6 @@ base = { path = "../base" }
cxx = { path = "../external/cxx-rs" }
byteorder = { workspace = true }
anyhow = { workspace = true }
clap = { workspace = true, features = ["derive"] }
size = { workspace = true }
quick-protobuf = { workspace = true }
argh = { workspace = true }

View File

@ -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; <command> --help for more info.")]
struct CpioCli {
#[command(subcommand)]
#[argh(subcommand)]
command: CpioCommands,
}
#[derive(Subcommand)]
#[derive(FromArgs)]
#[argh(subcommand)]
enum CpioCommands {
Test {},
Restore {},
Patch {},
Exists {
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 <entry> exists, otherwise return 1"
)]
struct Exists {
#[argh(positional, arg_name = "entry")]
path: String,
},
Backup {
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "backup",
description = "Create ramdisk backups from <orig>"
)]
struct Backup {
#[argh(positional, arg_name = "orig")]
origin: String,
},
Rm {
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "rm",
description = "Remove <entry>; specify [-r] to remove recursively"
)]
struct Remove {
#[argh(positional, arg_name = "entry")]
path: String,
#[arg(short)]
#[argh(switch, short = 'r', description = "recursive")]
recursive: bool,
},
Mv {
}
#[derive(FromArgs)]
#[argh(subcommand, name = "mv", description = "Move <source> to <dest>")]
struct Move {
#[argh(positional, arg_name = "source")]
from: String,
#[argh(positional, arg_name = "dest")]
to: String,
},
Extract {
#[arg(requires("out"))]
path: Option<String>,
out: Option<String>,
},
Mkdir {
#[arg(value_parser=parse_mode)]
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "extract",
description = "Extract <paths[0]> to <paths[1]>, or extract all entries to current directory if <paths> is not given"
)]
struct Extract {
#[argh(positional, greedy)]
paths: Vec<String>,
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "mkdir",
description = "Create directory <entry> in permissions <mode> (in octal)"
)]
struct MakeDir {
#[argh(positional, from_str_fn(parse_mode))]
mode: mode_t,
#[argh(positional, arg_name = "entry")]
dir: String,
},
Ln {
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "ln",
description = "Create a symlink to <target> with the name <entry>"
)]
struct Link {
#[argh(positional, arg_name = "entry")]
src: String,
#[argh(positional, arg_name = "target")]
dst: String,
},
Add {
#[arg(value_parser=parse_mode)]
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "add",
description = "Add <infile> as <entry> in permissions <mode> (in octal); replace <entry> 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,
},
Ls {
path: Option<String>,
#[arg(short)]
}
#[derive(FromArgs)]
#[argh(
subcommand,
name = "ls",
description = r#"List [<path>] ("/" 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::<Vec<_>>()
.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"));
}
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);
cpio.extract(
paths.get(0).map(|x| x.as_str()),
paths.get(1).map(|x| x.as_str()),
)?;
}
CpioCommands::List(List { path, recursive }) => {
cpio.ls(path.as_str(), *recursive);
exit(0);
}
}

View File

@ -60,32 +60,7 @@ Supported actions:
cpio <incpio> [commands...]
Do cpio commands to <incpio> (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 <incpio> --help" for supported commands.
dtb <file> <action> [args...]
Do dtb related actions to <file>