diff --git a/Cargo.lock b/Cargo.lock index f35b884..a38fa70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,6 +205,33 @@ dependencies = [ "phf_codegen", ] +[[package]] +name = "clap" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "colorchoice" version = "1.0.1" @@ -826,6 +853,7 @@ name = "rsbinder-tools" version = "0.3.0" dependencies = [ "anstyle", + "clap", "env_logger", "lazy_static", "log", @@ -961,6 +989,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.68" diff --git a/Cargo.toml b/Cargo.toml index 0610dc5..40c4a48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ version = "0.3.0" edition = "2021" license = "Apache-2.0" +authors = ["Jeff Kim "] homepage = "https://hiking90.github.io/rsbinder-book/" repository = "https://github.com/hiking90/rsbinder" rust-version = "1.71" @@ -34,4 +35,5 @@ tera = "1.19" similar = "2.4" pretty_hex = { version = "0.4", package = "pretty-hex" } downcast-rs = "1.2" -rustix = "0.38" \ No newline at end of file +rustix = "0.38" +clap = "4.5" \ No newline at end of file diff --git a/rsbinder-tools/Cargo.toml b/rsbinder-tools/Cargo.toml index ff157d3..1242dd1 100644 --- a/rsbinder-tools/Cargo.toml +++ b/rsbinder-tools/Cargo.toml @@ -1,18 +1,20 @@ [package] name = "rsbinder-tools" -version = { workspace = true } -edition = { workspace = true } -license = { workspace = true } +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true description = "This provides a few CLI binder tools for Linux." -homepage = { workspace = true } -repository = { workspace = true } +homepage.workspace = true +repository.workspace = true readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lazy_static = { workspace = true } -rsbinder = { workspace = true } -log = { workspace = true } -env_logger = { workspace = true } -anstyle = { workspace = true } +lazy_static.workspace = true +rsbinder.workspace = true +log.workspace = true +env_logger.workspace = true +anstyle.workspace = true +clap.workspace = true diff --git a/rsbinder-tools/src/bin/rsb_device.rs b/rsbinder-tools/src/bin/rsb_device.rs index d2e3635..39d2f43 100644 --- a/rsbinder-tools/src/bin/rsb_device.rs +++ b/rsbinder-tools/src/bin/rsb_device.rs @@ -5,6 +5,8 @@ use std::path::Path; use std::os::unix::fs::{PermissionsExt, symlink}; use std::process::Command; +use clap; + use rsbinder::*; use anstyle::*; @@ -24,13 +26,22 @@ fn log_err(msg: &str) { } fn main() -> std::result::Result<(), Box> { - let args: Vec = std::env::args().collect(); - - if args.len() < 2 { - println!("rsb_device - Create a binder device on binderfs"); - println!("Usage: rsb_device "); - return Ok(()) - } + let app = clap::Command::new("rsb_device") + .version(env!("CARGO_PKG_VERSION")) + .author(env!("CARGO_PKG_AUTHORS")) + .about("Creates a binder device on binderfs") + .arg(clap::Arg::new("device_name") + .help("Name of the binder device to create on binderfs, accessible via /dev/binderfs/") + .required(true) + .index(1)) + .after_help("Examples:\n \ + Create a new binder device named 'mybinder':\n \ + $ ./rsb_device mybinder\n \ + This command will create a device accessible at /dev/binderfs/mybinder.\n\n\ + Create a new binder device named 'test_device':\n \ + $ ./rsb_device test_device\n \ + This command will create a device accessible at /dev/binderfs/test_device.") + .get_matches(); env_logger::init(); @@ -40,7 +51,7 @@ fn main() -> std::result::Result<(), Box> { // Create binder control path if it doesn't exist. if !binderfs_path.exists() { std::fs::create_dir_all(binderfs_path) - .map(|_| log_ok(&format!("{} created successfully", binderfs_path.display()))) + .map(|_| log_ok(&format!("BinderFS root directory created at {}.", binderfs_path.display()))) .map_err(|err| log_err(&format!("Failed to create {}\n{}", binderfs_path.display(), err))).ok(); } else { log_ok(&format!("{} already exists", binderfs_path.display())); @@ -59,17 +70,18 @@ fn main() -> std::result::Result<(), Box> { .arg("binder") .arg(binderfs_path) .status() - .map(|_| log_ok(&format!("binder mounted successfully on {}", binderfs_path.display()))) + .map(|_| log_ok(&format!("BinderFS mounted at {}.", binderfs_path.display()))) .map_err(|err| log_err(&format!("Failed to mount binderfs\n{}", err))).ok(); } else { - log_ok(&format!("binderfs is already mounted on {}", binderfs_path.display())); + log_ok(&format!("BinderFS is already mounted on {}", binderfs_path.display())); } // Add binder device. - let device_name = args[1].as_str(); + let device_name = app.get_one::("device_name").unwrap(); + binderfs::add_device(control_path, device_name) - .map(|(major, minor)| { - log_ok(&format!("Allocated new binder device with major {major}, minor {minor}, and name [{}]", device_name)); + .map(|(_, _)| { + log_ok(&format!("New binder device allocated:\n\t- Device name: {device_name}\n\t- Accessible path: /dev/binderfs/{device_name}")); }) .map_err(|err| { if err.kind() == std::io::ErrorKind::AlreadyExists { @@ -83,14 +95,20 @@ fn main() -> std::result::Result<(), Box> { let mut perms = std::fs::metadata(&device_path).expect("IO error").permissions(); perms.set_mode(0o666); std::fs::set_permissions(&device_path, perms) - .map(|_| log_ok(&format!("The permission of device path({}) has been changed to 0666", + .map(|_| log_ok(&format!("Permission set to 0666 for {}", device_path.display()))) .map_err(|err| log_err(&format!("Failed to change the permission of device path({}) to 0666\n{}", device_path.display(), err))).ok(); symlink(binderfs_path.join(device_name), Path::new("/dev").join(device_name)) - .map(|_| log_ok(&format!("Created a symlink from {} to /dev/{}", binderfs_path.join(device_name).display(), device_name))) + .map(|_| log_ok(&format!("Symlink created from {} to /dev/{}", binderfs_path.join(device_name).display(), device_name))) .map_err(|err| log_err(&format!("Failed to create a symlink from {} to /dev/{}\n{}", binderfs_path.join(device_name).display(), device_name, err))).ok(); + println!("\nSummary:"); + println!("The binder device '{}' has been successfully created \ + and is accessible at /dev/binderfs/{} with full permissions (read/write by all users). \ + This setup facilitates IPC mechanisms within the Linux kernel.\n", + device_name, device_name); + Ok(()) }