use anyhow::{Ok, Result}; use clap::Parser; use std::path::PathBuf; #[cfg(target_os = "android")] use android_logger::Config; #[cfg(target_os = "android")] use log::LevelFilter; use crate::{apk_sign, debug, defs, event, module, utils}; /// KernelSU userspace cli #[derive(Parser, Debug)] #[command(author, version = defs::VERSION_NAME, about, long_about = None)] struct Args { #[command(subcommand)] command: Commands, } #[derive(clap::Subcommand, Debug)] enum Commands { /// Manage KernelSU modules Module { #[command(subcommand)] command: Module, }, /// Trigger `post-fs-data` event PostFsData, /// Trigger `service` event Services, /// Trigger `boot-complete` event BootCompleted, /// Install KernelSU userspace component to system Install, /// SELinux policy Patch tool Sepolicy { #[command(subcommand)] command: Sepolicy, }, /// Manage App Profiles Profile { #[command(subcommand)] command: Profile, }, /// Patch boot or init_boot images to apply KernelSU BootPatch { /// boot image path, if not specified, will try to find the boot image automatically #[arg(short, long)] boot: Option, /// kernel image path to replace #[arg(short, long)] kernel: Option, /// LKM module path to replace #[arg(short, long, requires("init"))] module: Option, /// init to be replaced, if use LKM, this must be specified #[arg(short, long, requires("module"))] init: Option, /// will use another slot when boot image is not specified #[arg(short = 'u', long, default_value = "false")] ota: bool, /// Flash it to boot partition after patch #[arg(short, long, default_value = "false")] flash: bool, /// output path, if not specified, will use current directory #[arg(short, long, default_value = None)] out: Option, /// magiskboot path, if not specified, will use builtin one #[arg(long, default_value = None)] magiskboot: Option, }, /// For developers Debug { #[command(subcommand)] command: Debug, }, } #[derive(clap::Subcommand, Debug)] enum Debug { /// Set the manager app, kernel CONFIG_KSU_DEBUG should be enabled. SetManager { /// manager package name #[arg(default_value_t = String::from("me.weishu.kernelsu"))] apk: String, }, /// Get apk size and hash GetSign { /// apk path apk: String, }, /// Root Shell Su { /// switch to gloabl mount namespace #[arg(short, long, default_value = "false")] global_mnt: bool, }, /// Get kernel version Version, Mount, /// Copy sparse file Xcp { /// source file src: String, /// destination file dst: String, }, /// Punch hole file PunchHole { /// file path file: String, }, /// For testing Test, } #[derive(clap::Subcommand, Debug)] enum Sepolicy { /// Patch sepolicy Patch { /// sepolicy statements sepolicy: String, }, /// Apply sepolicy from file Apply { /// sepolicy file path file: String, }, /// Check if sepolicy statement is supported/valid Check { /// sepolicy statements sepolicy: String, }, } #[derive(clap::Subcommand, Debug)] enum Module { /// Install module Install { /// module zip file path zip: String, }, /// Uninstall module Uninstall { /// module id id: String, }, /// enable module Enable { /// module id id: String, }, /// disable module Disable { // module id id: String, }, /// list all modules List, /// Shrink module image size Shrink, /// Link modules for manager LinkManager { /// module id mid: String, /// Manager's pid pid: i32, /// Manager's package name pkg: String, }, } #[derive(clap::Subcommand, Debug)] enum Profile { /// get root profile's selinux policy of GetSepolicy { /// package name package: String, }, /// set root profile's selinux policy of to SetSepolicy { /// package name package: String, /// policy statements policy: String, }, /// get template of GetTemplate { /// template id id: String, }, /// set template of to