Skip to content

Commit

Permalink
refactor cli
Browse files Browse the repository at this point in the history
  • Loading branch information
j-hc committed Sep 12, 2023
1 parent ac703e7 commit be4a0c7
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 221 deletions.
70 changes: 37 additions & 33 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::mem::size_of;
use std::ops::Range;
use std::panic::Location;
use std::process::{Command, ExitCode};
use termion::raw::IntoRawMode;

use termion::event::Key;
use termion::{clear, cursor};
Expand All @@ -17,7 +18,7 @@ mod colorize;
use colorize::ToColored;

mod menus;
use menus::{cursor_hide, cursor_show, select_menu, select_menu_numbered, select_menu_with_input};
use menus::Menus;

#[cfg(target_os = "android")]
const MODULE_DETACH: &str = "/data/adb/modules/zygisk-detach/detach.bin";
Expand Down Expand Up @@ -62,7 +63,6 @@ type IOError<T> = Result<T, CLIErr<io::Error>>;

fn main() -> ExitCode {
std::panic::set_hook(Box::new(|panic| {
use termion::raw::IntoRawMode;
if let Ok(mut stderr) = io::stderr().into_raw_mode() {
let _ = writeln!(stderr, "\r\n{panic}\r\n");
let _ = writeln!(stderr, "This should not have happened.\r");
Expand All @@ -73,6 +73,7 @@ fn main() -> ExitCode {
let _ = write!(stderr, "{}", cursor::Show);
}
}));
let mut menus = Menus::new();

let mut args = std::env::args().skip(1);
if matches!(args.next().as_deref(), Some("--serialize")) {
Expand All @@ -93,14 +94,14 @@ fn main() -> ExitCode {
}
}

let ret = match interactive() {
let ret = match interactive(&mut menus) {
Ok(()) => ExitCode::SUCCESS,
Err(err) => {
eprintln!("\rERROR: {err}");
ExitCode::FAILURE
}
};
cursor_show().unwrap();
menus.cursor_show().unwrap();
ret
}

Expand All @@ -126,19 +127,19 @@ fn serialize_txt(path: &str) -> IOError<()> {
Ok(())
}

fn interactive() -> IOError<()> {
cursor_hide()?;
fn interactive(menus: &mut Menus) -> IOError<()> {
menus.cursor_hide()?;
print!("zygisk-detach cli by github.com/j-hc\r\n\n");
loop {
match main_menu()? {
Op::DetachSelect => detach_menu()?,
Op::ReattachSelect => reattach_menu()?,
match main_menu(menus)? {
Op::DetachSelect => detach_menu(menus)?,
Op::ReattachSelect => reattach_menu(menus)?,
Op::Reset => {
if fs::remove_file(MODULE_DETACH).is_ok() {
let _ = kill_store();
text!("Reset");
text!(menus, "Reset");
} else {
text!("Already empty");
text!(menus, "Already empty");
}
}
Op::CopyToSd => {
Expand All @@ -147,9 +148,9 @@ fn interactive() -> IOError<()> {
#[cfg(target_os = "linux")]
const SDCARD_DETACH: &str = "detach_sdcard.bin";
match fs::copy(MODULE_DETACH, SDCARD_DETACH) {
Ok(_) => text!("Copied"),
Ok(_) => text!(menus, "Copied"),
Err(err) if err.kind() == io::ErrorKind::NotFound => {
text!("detach.bin not found");
text!(menus, "detach.bin not found");
}
Err(err) => return Err(err.into()),
}
Expand All @@ -160,30 +161,30 @@ fn interactive() -> IOError<()> {
}
}

fn reattach_menu() -> IOError<()> {
fn reattach_menu(menus: &mut Menus) -> IOError<()> {
let mut detach_txt = match fs::OpenOptions::new()
.write(true)
.read(true)
.open(MODULE_DETACH)
{
Ok(v) => v,
Err(e) if e.kind() == io::ErrorKind::NotFound => {
text!("detach.bin not found");
text!(menus, "detach.bin not found");
return Ok(());
}
Err(e) => return Err(e.into()),
};
let mut content = Vec::new();
detach_txt.read_to_end(&mut content)?;
detach_txt.seek(io::SeekFrom::Start(0))?;
let detached_apps = get_detached_apps(&content);
let detached_apps = get_detached_apps(menus, &content);
let detach_len = detached_apps.len();
if detach_len == 0 {
text!("detach.bin is empty");
text!(menus, "detach.bin is empty");
return Ok(());
}
let list = detached_apps.iter().map(|e| e.0.as_str());
let Some(i) = select_menu(
let Some(i) = menus.select_menu(
list,
"Select the app to re-attach ('q' to leave):",
"✖".red(),
Expand All @@ -193,15 +194,15 @@ fn reattach_menu() -> IOError<()> {
return Ok(());
};

textln!("{}: {}", "re-attach".red(), detached_apps[i].0);
textln!(menus, "{}: {}", "re-attach".red(), detached_apps[i].0);
content.drain(detached_apps[i].1.clone());
detach_txt.set_len(0)?;
detach_txt.write_all(&content)?;
detach_bin_changed();
Ok(())
}

fn get_detached_apps(detach_txt: &[u8]) -> Vec<(String, Range<usize>)> {
fn get_detached_apps(menus: &mut Menus, detach_txt: &[u8]) -> Vec<(String, Range<usize>)> {
let mut i = 0;
let mut detached = Vec::new();
while i < detach_txt.len() {
Expand All @@ -210,7 +211,7 @@ fn get_detached_apps(detach_txt: &[u8]) -> Vec<(String, Range<usize>)> {
i += SZ_LEN;
let Some(encoded_name) = &detach_txt.get(i..i + len as usize) else {
eprintln!("Corrupted detach.bin. Reset and try again.");
let _ = cursor_show();
let _ = menus.cursor_show();
std::process::exit(1);
};
let name = String::from_utf8(encoded_name.iter().step_by(2).cloned().collect()).unwrap();
Expand Down Expand Up @@ -244,7 +245,7 @@ enum Op {
Nop,
}

fn main_menu() -> IOError<Op> {
fn main_menu(menus: &mut Menus) -> IOError<Op> {
struct OpText {
desc: &'static str,
op: Op,
Expand All @@ -265,16 +266,16 @@ fn main_menu() -> IOError<Op> {
OpText::new("Reset detached apps", Op::Reset),
OpText::new("Copy detach.bin to /sdcard", Op::CopyToSd),
];
let i = select_menu_numbered(ops.iter(), Key::Char('q'), "- Selection:")?;
let i = menus.select_menu_numbered(ops.iter(), Key::Char('q'), "- Selection:")?;
use menus::SelectNumberedResp as SN;
match i {
SN::Index(i) => Ok(ops[i].op),
SN::UndefinedKey(Key::Char(c)) => {
text!("Undefined key {c:?}");
text!(menus, "Undefined key {c:?}");
Ok(Op::Nop)
}
SN::UndefinedKey(k @ (Key::Down | Key::Up | Key::Left | Key::Right)) => {
text!("Undefined key {k:?}");
text!(menus, "Undefined key {k:?}");
Ok(Op::Nop)
}
SN::Quit => Ok(Op::Quit),
Expand All @@ -300,7 +301,7 @@ fn bin_serialize(app: &str, sink: impl Write) -> IOError<()> {
Ok(())
}

fn detach_menu() -> IOError<()> {
fn detach_menu(menus: &mut Menus) -> IOError<()> {
let installed_apps = get_installed_apps()?;
let apps: Vec<&str> = installed_apps[..installed_apps.len() - 1]
.split(|&e| e == b'\n')
Expand All @@ -310,8 +311,8 @@ fn detach_menu() -> IOError<()> {
})
.map(|e| std::str::from_utf8(e).expect("non utf-8 package names?"))
.collect();
cursor_show()?;
let selected = select_menu_with_input(
menus.cursor_show()?;
let selected = menus.select_menu_with_input(
|input| {
let input = input.trim();
if !input.is_empty() {
Expand All @@ -330,7 +331,7 @@ fn detach_menu() -> IOError<()> {
"- app: ",
None,
)?;
cursor_hide()?;
menus.cursor_hide()?;
if let Some(detach_app) = selected {
let mut f = fs::OpenOptions::new()
.create(true)
Expand All @@ -339,13 +340,16 @@ fn detach_menu() -> IOError<()> {
.open(MODULE_DETACH)?;
let mut buf: Vec<u8> = Vec::new();
f.read_to_end(&mut buf)?;
if !get_detached_apps(&buf).iter().any(|(s, _)| s == detach_app) {
if !get_detached_apps(menus, &buf)
.iter()
.any(|(s, _)| s == detach_app)
{
bin_serialize(detach_app, f)?;
textln!("{} {}", "detach:".green(), detach_app);
textln!("Changes are applied. No need for a reboot!");
textln!(menus, "{} {}", "detach:".green(), detach_app);
textln!(menus, "Changes are applied. No need for a reboot!");
detach_bin_changed();
} else {
textln!("{} {}", "already detached:".green(), detach_app);
textln!(menus, "{} {}", "already detached:".green(), detach_app);
}
}
Ok(())
Expand Down
Loading

0 comments on commit be4a0c7

Please sign in to comment.