mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Cargo fmt tools
This commit is contained in:
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{value_parser, Arg, Command};
|
use clap::{Arg, Command, value_parser};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
afc::{opcode::AfcFopenMode, AfcClient},
|
|
||||||
house_arrest::HouseArrestClient,
|
|
||||||
IdeviceService,
|
IdeviceService,
|
||||||
|
afc::{AfcClient, opcode::AfcFopenMode},
|
||||||
|
house_arrest::HouseArrestClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{amfi::AmfiClient, IdeviceService};
|
use idevice::{IdeviceService, amfi::AmfiClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
core_device::AppServiceClient, core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake,
|
IdeviceService, RsdService, core_device::AppServiceClient, core_device_proxy::CoreDeviceProxy,
|
||||||
IdeviceService, RsdService,
|
rsd::RsdHandshake,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use clap::{arg, Arg, Command};
|
use clap::{Arg, Command, arg};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
companion_proxy::CompanionProxy, core_device_proxy::CoreDeviceProxy, pretty_print_dictionary,
|
IdeviceService, RsdService, companion_proxy::CompanionProxy,
|
||||||
pretty_print_plist, rsd::RsdHandshake, IdeviceService, RsdService,
|
core_device_proxy::CoreDeviceProxy, pretty_print_dictionary, pretty_print_plist,
|
||||||
|
rsd::RsdHandshake,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
crashreportcopymobile::{flush_reports, CrashReportCopyMobileClient},
|
|
||||||
IdeviceService,
|
IdeviceService,
|
||||||
|
crashreportcopymobile::{CrashReportCopyMobileClient, flush_reports},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ use std::io::Write;
|
|||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
core_device_proxy::CoreDeviceProxy, debug_proxy::DebugProxyClient, rsd::RsdHandshake,
|
IdeviceService, RsdService, core_device_proxy::CoreDeviceProxy, debug_proxy::DebugProxyClient,
|
||||||
IdeviceService, RsdService,
|
rsd::RsdHandshake,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
// idevice Rust implementation of libimobiledevice's idevicediagnostics
|
// idevice Rust implementation of libimobiledevice's idevicediagnostics
|
||||||
|
|
||||||
use clap::{Arg, Command, ArgMatches};
|
use clap::{Arg, ArgMatches, Command};
|
||||||
use idevice::{services::diagnostics_relay::DiagnosticsRelayClient, IdeviceService};
|
use idevice::{IdeviceService, services::diagnostics_relay::DiagnosticsRelayClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
@@ -43,20 +43,20 @@ async fn main() {
|
|||||||
Arg::new("plane")
|
Arg::new("plane")
|
||||||
.long("plane")
|
.long("plane")
|
||||||
.value_name("PLANE")
|
.value_name("PLANE")
|
||||||
.help("IORegistry plane to query (e.g., IODeviceTree, IOService)")
|
.help("IORegistry plane to query (e.g., IODeviceTree, IOService)"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("name")
|
Arg::new("name")
|
||||||
.long("name")
|
.long("name")
|
||||||
.value_name("NAME")
|
.value_name("NAME")
|
||||||
.help("Entry name to filter by")
|
.help("Entry name to filter by"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("class")
|
Arg::new("class")
|
||||||
.long("class")
|
.long("class")
|
||||||
.value_name("CLASS")
|
.value_name("CLASS")
|
||||||
.help("Entry class to filter by")
|
.help("Entry class to filter by"),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("mobilegestalt")
|
Command::new("mobilegestalt")
|
||||||
@@ -67,45 +67,23 @@ async fn main() {
|
|||||||
.value_name("KEYS")
|
.value_name("KEYS")
|
||||||
.help("Comma-separated list of keys to query")
|
.help("Comma-separated list of keys to query")
|
||||||
.value_delimiter(',')
|
.value_delimiter(',')
|
||||||
.num_args(1..)
|
.num_args(1..),
|
||||||
)
|
),
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("gasguage")
|
|
||||||
.about("Print gas gauge (battery) information")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("nand")
|
|
||||||
.about("Print NAND flash information")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("all")
|
|
||||||
.about("Print all available diagnostics information")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("wifi")
|
|
||||||
.about("Print WiFi diagnostics information")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("goodbye")
|
|
||||||
.about("Send Goodbye to diagnostics relay")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("restart")
|
|
||||||
.about("Restart the device")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("shutdown")
|
|
||||||
.about("Shutdown the device")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
Command::new("sleep")
|
|
||||||
.about("Put the device to sleep")
|
|
||||||
)
|
)
|
||||||
|
.subcommand(Command::new("gasguage").about("Print gas gauge (battery) information"))
|
||||||
|
.subcommand(Command::new("nand").about("Print NAND flash information"))
|
||||||
|
.subcommand(Command::new("all").about("Print all available diagnostics information"))
|
||||||
|
.subcommand(Command::new("wifi").about("Print WiFi diagnostics information"))
|
||||||
|
.subcommand(Command::new("goodbye").about("Send Goodbye to diagnostics relay"))
|
||||||
|
.subcommand(Command::new("restart").about("Restart the device"))
|
||||||
|
.subcommand(Command::new("shutdown").about("Shutdown the device"))
|
||||||
|
.subcommand(Command::new("sleep").about("Put the device to sleep"))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("idevicediagnostics - interact with the diagnostics interface of a device. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"idevicediagnostics - interact with the diagnostics interface of a device. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -187,7 +165,8 @@ async fn handle_ioregistry(client: &mut DiagnosticsRelayClient, matches: &ArgMat
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_mobilegestalt(client: &mut DiagnosticsRelayClient, matches: &ArgMatches) {
|
async fn handle_mobilegestalt(client: &mut DiagnosticsRelayClient, matches: &ArgMatches) {
|
||||||
let keys = matches.get_many::<String>("keys")
|
let keys = matches
|
||||||
|
.get_many::<String>("keys")
|
||||||
.map(|values| values.map(|s| s.to_string()).collect::<Vec<_>>());
|
.map(|values| values.map(|s| s.to_string()).collect::<Vec<_>>());
|
||||||
|
|
||||||
match client.mobilegestalt(keys).await {
|
match client.mobilegestalt(keys).await {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Heartbeat client
|
// Heartbeat client
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{heartbeat::HeartbeatClient, IdeviceService};
|
use idevice::{IdeviceService, heartbeat::HeartbeatClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// idevice Rust implementation of libimobiledevice's ideviceinfo
|
// idevice Rust implementation of libimobiledevice's ideviceinfo
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{lockdown::LockdownClient, IdeviceService};
|
use idevice::{IdeviceService, lockdown::LockdownClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
@@ -39,7 +39,9 @@ async fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("ideviceinfo - get information from the idevice. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"ideviceinfo - get information from the idevice. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Just lists apps for now
|
// Just lists apps for now
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{installation_proxy::InstallationProxyClient, IdeviceService};
|
use idevice::{IdeviceService, installation_proxy::InstallationProxyClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
@@ -47,7 +47,9 @@ async fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("instproxy - query and manage apps installed on a device. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"instproxy - query and manage apps installed on a device. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Just lists apps for now
|
// Just lists apps for now
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake, IdeviceService, RsdService};
|
use idevice::{IdeviceService, RsdService, core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use clap::{arg, Arg, Command};
|
use clap::{Arg, Command, arg};
|
||||||
use idevice::{lockdown::LockdownClient, pretty_print_plist, IdeviceService};
|
use idevice::{IdeviceService, lockdown::LockdownClient, pretty_print_plist};
|
||||||
use plist::Value;
|
use plist::Value;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
@@ -52,7 +52,9 @@ async fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("lockdown - query and manage values on a device. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"lockdown - query and manage values on a device. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{arg, value_parser, Arg, Command};
|
use clap::{Arg, Command, arg, value_parser};
|
||||||
use idevice::{misagent::MisagentClient, IdeviceService};
|
use idevice::{IdeviceService, misagent::MisagentClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
@@ -52,7 +52,9 @@ async fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("mounter - query and manage images mounted on a device. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"mounter - query and manage images mounted on a device. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
// Mobile Backup 2 tool for iOS devices
|
// Mobile Backup 2 tool for iOS devices
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{mobilebackup2::{MobileBackup2Client, RestoreOptions}, IdeviceService};
|
use idevice::{
|
||||||
|
IdeviceService,
|
||||||
|
mobilebackup2::{MobileBackup2Client, RestoreOptions},
|
||||||
|
};
|
||||||
use plist::Dictionary;
|
use plist::Dictionary;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
@@ -44,13 +47,18 @@ async fn main() {
|
|||||||
Command::new("info")
|
Command::new("info")
|
||||||
.about("Get backup information from a local backup directory")
|
.about("Get backup information from a local backup directory")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
||||||
.arg(Arg::new("source").long("source").value_name("SOURCE").help("Source identifier (defaults to current UDID)"))
|
.arg(
|
||||||
|
Arg::new("source")
|
||||||
|
.long("source")
|
||||||
|
.value_name("SOURCE")
|
||||||
|
.help("Source identifier (defaults to current UDID)"),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("list")
|
Command::new("list")
|
||||||
.about("List files of the last backup from a local backup directory")
|
.about("List files of the last backup from a local backup directory")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
||||||
.arg(Arg::new("source").long("source").value_name("SOURCE"))
|
.arg(Arg::new("source").long("source").value_name("SOURCE")),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("backup")
|
Command::new("backup")
|
||||||
@@ -79,41 +87,81 @@ async fn main() {
|
|||||||
Command::new("restore")
|
Command::new("restore")
|
||||||
.about("Restore from a local backup directory (DeviceLink)")
|
.about("Restore from a local backup directory (DeviceLink)")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
||||||
.arg(Arg::new("source").long("source").value_name("SOURCE").help("Source UDID; defaults to current device UDID"))
|
.arg(
|
||||||
.arg(Arg::new("password").long("password").value_name("PWD").help("Backup password if encrypted"))
|
Arg::new("source")
|
||||||
.arg(Arg::new("no-reboot").long("no-reboot").action(clap::ArgAction::SetTrue))
|
.long("source")
|
||||||
.arg(Arg::new("no-copy").long("no-copy").action(clap::ArgAction::SetTrue))
|
.value_name("SOURCE")
|
||||||
.arg(Arg::new("no-settings").long("no-settings").action(clap::ArgAction::SetTrue))
|
.help("Source UDID; defaults to current device UDID"),
|
||||||
.arg(Arg::new("system").long("system").action(clap::ArgAction::SetTrue))
|
)
|
||||||
.arg(Arg::new("remove").long("remove").action(clap::ArgAction::SetTrue))
|
.arg(
|
||||||
|
Arg::new("password")
|
||||||
|
.long("password")
|
||||||
|
.value_name("PWD")
|
||||||
|
.help("Backup password if encrypted"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("no-reboot")
|
||||||
|
.long("no-reboot")
|
||||||
|
.action(clap::ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("no-copy")
|
||||||
|
.long("no-copy")
|
||||||
|
.action(clap::ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("no-settings")
|
||||||
|
.long("no-settings")
|
||||||
|
.action(clap::ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("system")
|
||||||
|
.long("system")
|
||||||
|
.action(clap::ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("remove")
|
||||||
|
.long("remove")
|
||||||
|
.action(clap::ArgAction::SetTrue),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("unback")
|
Command::new("unback")
|
||||||
.about("Unpack a complete backup to device hierarchy")
|
.about("Unpack a complete backup to device hierarchy")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
||||||
.arg(Arg::new("source").long("source").value_name("SOURCE"))
|
.arg(Arg::new("source").long("source").value_name("SOURCE"))
|
||||||
.arg(Arg::new("password").long("password").value_name("PWD"))
|
.arg(Arg::new("password").long("password").value_name("PWD")),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("extract")
|
Command::new("extract")
|
||||||
.about("Extract a file from a previous backup")
|
.about("Extract a file from a previous backup")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
||||||
.arg(Arg::new("source").long("source").value_name("SOURCE"))
|
.arg(Arg::new("source").long("source").value_name("SOURCE"))
|
||||||
.arg(Arg::new("domain").long("domain").value_name("DOMAIN").required(true))
|
.arg(
|
||||||
.arg(Arg::new("path").long("path").value_name("REL_PATH").required(true))
|
Arg::new("domain")
|
||||||
.arg(Arg::new("password").long("password").value_name("PWD"))
|
.long("domain")
|
||||||
|
.value_name("DOMAIN")
|
||||||
|
.required(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("path")
|
||||||
|
.long("path")
|
||||||
|
.value_name("REL_PATH")
|
||||||
|
.required(true),
|
||||||
|
)
|
||||||
|
.arg(Arg::new("password").long("password").value_name("PWD")),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("change-password")
|
Command::new("change-password")
|
||||||
.about("Change backup password")
|
.about("Change backup password")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
||||||
.arg(Arg::new("old").long("old").value_name("OLD"))
|
.arg(Arg::new("old").long("old").value_name("OLD"))
|
||||||
.arg(Arg::new("new").long("new").value_name("NEW"))
|
.arg(Arg::new("new").long("new").value_name("NEW")),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("erase-device")
|
Command::new("erase-device")
|
||||||
.about("Erase the device via mobilebackup2")
|
.about("Erase the device via mobilebackup2")
|
||||||
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true))
|
.arg(Arg::new("dir").long("dir").value_name("DIR").required(true)),
|
||||||
)
|
)
|
||||||
.subcommand(Command::new("freespace").about("Get free space information"))
|
.subcommand(Command::new("freespace").about("Get free space information"))
|
||||||
.subcommand(Command::new("encryption").about("Check backup encryption status"))
|
.subcommand(Command::new("encryption").about("Check backup encryption status"))
|
||||||
@@ -129,14 +177,14 @@ async fn main() {
|
|||||||
let host = matches.get_one::<String>("host");
|
let host = matches.get_one::<String>("host");
|
||||||
let pairing_file = matches.get_one::<String>("pairing_file");
|
let pairing_file = matches.get_one::<String>("pairing_file");
|
||||||
|
|
||||||
let provider = match common::get_provider(udid, host, pairing_file, "mobilebackup2-jkcoxson").await
|
let provider =
|
||||||
{
|
match common::get_provider(udid, host, pairing_file, "mobilebackup2-jkcoxson").await {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Error creating provider: {e}");
|
eprintln!("Error creating provider: {e}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut backup_client = match MobileBackup2Client::connect(&*provider).await {
|
let mut backup_client = match MobileBackup2Client::connect(&*provider).await {
|
||||||
Ok(client) => client,
|
Ok(client) => client,
|
||||||
@@ -153,7 +201,9 @@ async fn main() {
|
|||||||
match backup_client.info_from_path(Path::new(dir), source).await {
|
match backup_client.info_from_path(Path::new(dir), source).await {
|
||||||
Ok(dict) => {
|
Ok(dict) => {
|
||||||
println!("Backup Information:");
|
println!("Backup Information:");
|
||||||
for (k, v) in dict { println!(" {k}: {v:?}"); }
|
for (k, v) in dict {
|
||||||
|
println!(" {k}: {v:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => eprintln!("Failed to get info: {e}"),
|
Err(e) => eprintln!("Failed to get info: {e}"),
|
||||||
}
|
}
|
||||||
@@ -164,7 +214,9 @@ async fn main() {
|
|||||||
match backup_client.list_from_path(Path::new(dir), source).await {
|
match backup_client.list_from_path(Path::new(dir), source).await {
|
||||||
Ok(dict) => {
|
Ok(dict) => {
|
||||||
println!("List Response:");
|
println!("List Response:");
|
||||||
for (k, v) in dict { println!(" {k}: {v:?}"); }
|
for (k, v) in dict {
|
||||||
|
println!(" {k}: {v:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => eprintln!("Failed to list: {e}"),
|
Err(e) => eprintln!("Failed to list: {e}"),
|
||||||
}
|
}
|
||||||
@@ -172,7 +224,9 @@ async fn main() {
|
|||||||
Some(("backup", sub_matches)) => {
|
Some(("backup", sub_matches)) => {
|
||||||
let target = sub_matches.get_one::<String>("target").map(|s| s.as_str());
|
let target = sub_matches.get_one::<String>("target").map(|s| s.as_str());
|
||||||
let source = sub_matches.get_one::<String>("source").map(|s| s.as_str());
|
let source = sub_matches.get_one::<String>("source").map(|s| s.as_str());
|
||||||
let dir = sub_matches.get_one::<String>("dir").expect("dir is required");
|
let dir = sub_matches
|
||||||
|
.get_one::<String>("dir")
|
||||||
|
.expect("dir is required");
|
||||||
|
|
||||||
println!("Starting backup operation...");
|
println!("Starting backup operation...");
|
||||||
let res = backup_client
|
let res = backup_client
|
||||||
@@ -190,13 +244,28 @@ async fn main() {
|
|||||||
let dir = sub.get_one::<String>("dir").unwrap();
|
let dir = sub.get_one::<String>("dir").unwrap();
|
||||||
let source = sub.get_one::<String>("source").map(|s| s.as_str());
|
let source = sub.get_one::<String>("source").map(|s| s.as_str());
|
||||||
let mut ropts = RestoreOptions::new();
|
let mut ropts = RestoreOptions::new();
|
||||||
if sub.get_flag("no-reboot") { ropts = ropts.with_reboot(false); }
|
if sub.get_flag("no-reboot") {
|
||||||
if sub.get_flag("no-copy") { ropts = ropts.with_copy(false); }
|
ropts = ropts.with_reboot(false);
|
||||||
if sub.get_flag("no-settings") { ropts = ropts.with_preserve_settings(false); }
|
}
|
||||||
if sub.get_flag("system") { ropts = ropts.with_system_files(true); }
|
if sub.get_flag("no-copy") {
|
||||||
if sub.get_flag("remove") { ropts = ropts.with_remove_items_not_restored(true); }
|
ropts = ropts.with_copy(false);
|
||||||
if let Some(pw) = sub.get_one::<String>("password") { ropts = ropts.with_password(pw); }
|
}
|
||||||
match backup_client.restore_from_path(Path::new(dir), source, Some(ropts)).await {
|
if sub.get_flag("no-settings") {
|
||||||
|
ropts = ropts.with_preserve_settings(false);
|
||||||
|
}
|
||||||
|
if sub.get_flag("system") {
|
||||||
|
ropts = ropts.with_system_files(true);
|
||||||
|
}
|
||||||
|
if sub.get_flag("remove") {
|
||||||
|
ropts = ropts.with_remove_items_not_restored(true);
|
||||||
|
}
|
||||||
|
if let Some(pw) = sub.get_one::<String>("password") {
|
||||||
|
ropts = ropts.with_password(pw);
|
||||||
|
}
|
||||||
|
match backup_client
|
||||||
|
.restore_from_path(Path::new(dir), source, Some(ropts))
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => println!("Restore flow finished"),
|
Ok(_) => println!("Restore flow finished"),
|
||||||
Err(e) => eprintln!("Restore failed: {e}"),
|
Err(e) => eprintln!("Restore failed: {e}"),
|
||||||
}
|
}
|
||||||
@@ -205,7 +274,10 @@ async fn main() {
|
|||||||
let dir = sub.get_one::<String>("dir").unwrap();
|
let dir = sub.get_one::<String>("dir").unwrap();
|
||||||
let source = sub.get_one::<String>("source").map(|s| s.as_str());
|
let source = sub.get_one::<String>("source").map(|s| s.as_str());
|
||||||
let password = sub.get_one::<String>("password").map(|s| s.as_str());
|
let password = sub.get_one::<String>("password").map(|s| s.as_str());
|
||||||
match backup_client.unback_from_path(Path::new(dir), password, source).await {
|
match backup_client
|
||||||
|
.unback_from_path(Path::new(dir), password, source)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => println!("Unback finished"),
|
Ok(_) => println!("Unback finished"),
|
||||||
Err(e) => eprintln!("Unback failed: {e}"),
|
Err(e) => eprintln!("Unback failed: {e}"),
|
||||||
}
|
}
|
||||||
@@ -216,7 +288,10 @@ async fn main() {
|
|||||||
let domain = sub.get_one::<String>("domain").unwrap();
|
let domain = sub.get_one::<String>("domain").unwrap();
|
||||||
let rel = sub.get_one::<String>("path").unwrap();
|
let rel = sub.get_one::<String>("path").unwrap();
|
||||||
let password = sub.get_one::<String>("password").map(|s| s.as_str());
|
let password = sub.get_one::<String>("password").map(|s| s.as_str());
|
||||||
match backup_client.extract_from_path(domain, rel, Path::new(dir), password, source).await {
|
match backup_client
|
||||||
|
.extract_from_path(domain, rel, Path::new(dir), password, source)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => println!("Extract finished"),
|
Ok(_) => println!("Extract finished"),
|
||||||
Err(e) => eprintln!("Extract failed: {e}"),
|
Err(e) => eprintln!("Extract failed: {e}"),
|
||||||
}
|
}
|
||||||
@@ -225,7 +300,10 @@ async fn main() {
|
|||||||
let dir = sub.get_one::<String>("dir").unwrap();
|
let dir = sub.get_one::<String>("dir").unwrap();
|
||||||
let old = sub.get_one::<String>("old").map(|s| s.as_str());
|
let old = sub.get_one::<String>("old").map(|s| s.as_str());
|
||||||
let newv = sub.get_one::<String>("new").map(|s| s.as_str());
|
let newv = sub.get_one::<String>("new").map(|s| s.as_str());
|
||||||
match backup_client.change_password_from_path(Path::new(dir), old, newv).await {
|
match backup_client
|
||||||
|
.change_password_from_path(Path::new(dir), old, newv)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => println!("Change password finished"),
|
Ok(_) => println!("Change password finished"),
|
||||||
Err(e) => eprintln!("Change password failed: {e}"),
|
Err(e) => eprintln!("Change password failed: {e}"),
|
||||||
}
|
}
|
||||||
@@ -237,23 +315,22 @@ async fn main() {
|
|||||||
Err(e) => eprintln!("Erase device failed: {e}"),
|
Err(e) => eprintln!("Erase device failed: {e}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(("freespace", _)) => {
|
Some(("freespace", _)) => match backup_client.get_freespace().await {
|
||||||
match backup_client.get_freespace().await {
|
Ok(freespace) => {
|
||||||
Ok(freespace) => {
|
let freespace_gb = freespace as f64 / (1024.0 * 1024.0 * 1024.0);
|
||||||
let freespace_gb = freespace as f64 / (1024.0 * 1024.0 * 1024.0);
|
println!("Free space: {freespace} bytes ({freespace_gb:.2} GB)");
|
||||||
println!("Free space: {freespace} bytes ({freespace_gb:.2} GB)");
|
|
||||||
}
|
|
||||||
Err(e) => eprintln!("Failed to get free space: {e}"),
|
|
||||||
}
|
}
|
||||||
}
|
Err(e) => eprintln!("Failed to get free space: {e}"),
|
||||||
Some(("encryption", _)) => {
|
},
|
||||||
match backup_client.check_backup_encryption().await {
|
Some(("encryption", _)) => match backup_client.check_backup_encryption().await {
|
||||||
Ok(is_encrypted) => {
|
Ok(is_encrypted) => {
|
||||||
println!("Backup encryption: {}", if is_encrypted { "Enabled" } else { "Disabled" });
|
println!(
|
||||||
}
|
"Backup encryption: {}",
|
||||||
Err(e) => eprintln!("Failed to check backup encryption: {e}"),
|
if is_encrypted { "Enabled" } else { "Disabled" }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
Err(e) => eprintln!("Failed to check backup encryption: {e}"),
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
println!("No subcommand provided. Use --help for available commands.");
|
println!("No subcommand provided. Use --help for available commands.");
|
||||||
}
|
}
|
||||||
@@ -266,8 +343,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use idevice::services::mobilebackup2::{
|
use idevice::services::mobilebackup2::{
|
||||||
DL_CODE_ERROR_LOCAL as CODE_ERROR_LOCAL,
|
DL_CODE_ERROR_LOCAL as CODE_ERROR_LOCAL, DL_CODE_FILE_DATA as CODE_FILE_DATA,
|
||||||
DL_CODE_FILE_DATA as CODE_FILE_DATA,
|
|
||||||
DL_CODE_SUCCESS as CODE_SUCCESS,
|
DL_CODE_SUCCESS as CODE_SUCCESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -297,26 +373,36 @@ async fn process_dl_loop(
|
|||||||
}
|
}
|
||||||
"DLMessageCreateDirectory" => {
|
"DLMessageCreateDirectory" => {
|
||||||
let status = create_directory_from_message(&value, host_dir);
|
let status = create_directory_from_message(&value, host_dir);
|
||||||
client
|
client.send_status_response(status, None, None).await?;
|
||||||
.send_status_response(status, None, None)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
"DLMessageMoveFiles" | "DLMessageMoveItems" => {
|
"DLMessageMoveFiles" | "DLMessageMoveItems" => {
|
||||||
let status = move_files_from_message(&value, host_dir);
|
let status = move_files_from_message(&value, host_dir);
|
||||||
client
|
client
|
||||||
.send_status_response(status, None, Some(plist::Value::Dictionary(Dictionary::new())))
|
.send_status_response(
|
||||||
|
status,
|
||||||
|
None,
|
||||||
|
Some(plist::Value::Dictionary(Dictionary::new())),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
"DLMessageRemoveFiles" | "DLMessageRemoveItems" => {
|
"DLMessageRemoveFiles" | "DLMessageRemoveItems" => {
|
||||||
let status = remove_files_from_message(&value, host_dir);
|
let status = remove_files_from_message(&value, host_dir);
|
||||||
client
|
client
|
||||||
.send_status_response(status, None, Some(plist::Value::Dictionary(Dictionary::new())))
|
.send_status_response(
|
||||||
|
status,
|
||||||
|
None,
|
||||||
|
Some(plist::Value::Dictionary(Dictionary::new())),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
"DLMessageCopyItem" => {
|
"DLMessageCopyItem" => {
|
||||||
let status = copy_item_from_message(&value, host_dir);
|
let status = copy_item_from_message(&value, host_dir);
|
||||||
client
|
client
|
||||||
.send_status_response(status, None, Some(plist::Value::Dictionary(Dictionary::new())))
|
.send_status_response(
|
||||||
|
status,
|
||||||
|
None,
|
||||||
|
Some(plist::Value::Dictionary(Dictionary::new())),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
"DLMessageProcessMessage" => {
|
"DLMessageProcessMessage" => {
|
||||||
@@ -353,23 +439,24 @@ async fn handle_download_files(
|
|||||||
&& let Some(plist::Value::Array(files)) = arr.get(1)
|
&& let Some(plist::Value::Array(files)) = arr.get(1)
|
||||||
{
|
{
|
||||||
for pv in files {
|
for pv in files {
|
||||||
if let Some(path) = pv.as_string()
|
if let Some(path) = pv.as_string()
|
||||||
&& let Err(e) = send_single_file(client, host_dir, path).await
|
&& let Err(e) = send_single_file(client, host_dir, path).await
|
||||||
{
|
{
|
||||||
eprintln!("Failed to send file {path}: {e}");
|
eprintln!("Failed to send file {path}: {e}");
|
||||||
err_any = true;
|
err_any = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// terminating zero dword
|
// terminating zero dword
|
||||||
client
|
client.idevice.send_raw(&0u32.to_be_bytes()).await?;
|
||||||
.idevice
|
|
||||||
.send_raw(&0u32.to_be_bytes())
|
|
||||||
.await?;
|
|
||||||
// status response
|
// status response
|
||||||
if err_any {
|
if err_any {
|
||||||
client
|
client
|
||||||
.send_status_response(-13, Some("Multi status"), Some(plist::Value::Dictionary(Dictionary::new())))
|
.send_status_response(
|
||||||
|
-13,
|
||||||
|
Some("Multi status"),
|
||||||
|
Some(plist::Value::Dictionary(Dictionary::new())),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
client
|
client
|
||||||
@@ -446,7 +533,8 @@ async fn handle_upload_files(
|
|||||||
if let Some(parent) = dst.parent() {
|
if let Some(parent) = dst.parent() {
|
||||||
let _ = fs::create_dir_all(parent);
|
let _ = fs::create_dir_all(parent);
|
||||||
}
|
}
|
||||||
let mut file = std::fs::File::create(&dst).map_err(|e| idevice::IdeviceError::InternalError(e.to_string()))?;
|
let mut file = std::fs::File::create(&dst)
|
||||||
|
.map_err(|e| idevice::IdeviceError::InternalError(e.to_string()))?;
|
||||||
loop {
|
loop {
|
||||||
let nlen = read_be_u32(client).await?;
|
let nlen = read_be_u32(client).await?;
|
||||||
if nlen == 0 {
|
if nlen == 0 {
|
||||||
@@ -456,7 +544,8 @@ async fn handle_upload_files(
|
|||||||
if code == CODE_FILE_DATA {
|
if code == CODE_FILE_DATA {
|
||||||
let size = (nlen - 1) as usize;
|
let size = (nlen - 1) as usize;
|
||||||
let data = read_exact(client, size).await?;
|
let data = read_exact(client, size).await?;
|
||||||
file.write_all(&data).map_err(|e| idevice::IdeviceError::InternalError(e.to_string()))?;
|
file.write_all(&data)
|
||||||
|
.map_err(|e| idevice::IdeviceError::InternalError(e.to_string()))?;
|
||||||
} else {
|
} else {
|
||||||
let _ = read_exact(client, (nlen - 1) as usize).await?;
|
let _ = read_exact(client, (nlen - 1) as usize).await?;
|
||||||
}
|
}
|
||||||
@@ -478,11 +567,17 @@ async fn read_one(client: &mut MobileBackup2Client) -> Result<u8, idevice::Idevi
|
|||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_exact(client: &mut MobileBackup2Client, size: usize) -> Result<Vec<u8>, idevice::IdeviceError> {
|
async fn read_exact(
|
||||||
|
client: &mut MobileBackup2Client,
|
||||||
|
size: usize,
|
||||||
|
) -> Result<Vec<u8>, idevice::IdeviceError> {
|
||||||
client.idevice.read_raw(size).await
|
client.idevice.read_raw(size).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_exact_string(client: &mut MobileBackup2Client, size: usize) -> Result<String, idevice::IdeviceError> {
|
async fn read_exact_string(
|
||||||
|
client: &mut MobileBackup2Client,
|
||||||
|
size: usize,
|
||||||
|
) -> Result<String, idevice::IdeviceError> {
|
||||||
let buf = client.idevice.read_raw(size).await?;
|
let buf = client.idevice.read_raw(size).await?;
|
||||||
Ok(String::from_utf8_lossy(&buf).to_string())
|
Ok(String::from_utf8_lossy(&buf).to_string())
|
||||||
}
|
}
|
||||||
@@ -532,7 +627,9 @@ fn remove_files_from_message(dl_value: &plist::Value, host_dir: &Path) -> i64 {
|
|||||||
if let Some(p) = it.as_string() {
|
if let Some(p) = it.as_string() {
|
||||||
let path = host_dir.join(p);
|
let path = host_dir.join(p);
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
if fs::remove_dir_all(&path).is_err() { return -1; }
|
if fs::remove_dir_all(&path).is_err() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else if path.exists() && fs::remove_file(&path).is_err() {
|
} else if path.exists() && fs::remove_file(&path).is_err() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -546,16 +643,25 @@ fn remove_files_from_message(dl_value: &plist::Value, host_dir: &Path) -> i64 {
|
|||||||
fn copy_item_from_message(dl_value: &plist::Value, host_dir: &Path) -> i64 {
|
fn copy_item_from_message(dl_value: &plist::Value, host_dir: &Path) -> i64 {
|
||||||
if let plist::Value::Array(arr) = dl_value
|
if let plist::Value::Array(arr) = dl_value
|
||||||
&& arr.len() >= 3
|
&& arr.len() >= 3
|
||||||
&& let (Some(plist::Value::String(src)), Some(plist::Value::String(dst))) = (arr.get(1), arr.get(2))
|
&& let (Some(plist::Value::String(src)), Some(plist::Value::String(dst))) =
|
||||||
|
(arr.get(1), arr.get(2))
|
||||||
{
|
{
|
||||||
let from = host_dir.join(src);
|
let from = host_dir.join(src);
|
||||||
let to = host_dir.join(dst);
|
let to = host_dir.join(dst);
|
||||||
if let Some(parent) = to.parent() { let _ = fs::create_dir_all(parent); }
|
if let Some(parent) = to.parent() {
|
||||||
|
let _ = fs::create_dir_all(parent);
|
||||||
|
}
|
||||||
if from.is_dir() {
|
if from.is_dir() {
|
||||||
// shallow copy: create dir
|
// shallow copy: create dir
|
||||||
return match fs::create_dir_all(&to) { Ok(_) => 0, Err(_) => -1 };
|
return match fs::create_dir_all(&to) {
|
||||||
|
Ok(_) => 0,
|
||||||
|
Err(_) => -1,
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return match fs::copy(&from, &to) { Ok(_) => 0, Err(_) => -1 };
|
return match fs::copy(&from, &to) {
|
||||||
|
Ok(_) => 0,
|
||||||
|
Err(_) => -1,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-1
|
-1
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
use std::{io::Write, path::PathBuf};
|
use std::{io::Write, path::PathBuf};
|
||||||
|
|
||||||
use clap::{arg, value_parser, Arg, Command};
|
use clap::{Arg, Command, arg, value_parser};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
lockdown::LockdownClient, mobile_image_mounter::ImageMounter, pretty_print_plist,
|
IdeviceService, lockdown::LockdownClient, mobile_image_mounter::ImageMounter,
|
||||||
IdeviceService,
|
pretty_print_plist,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
@@ -67,7 +67,9 @@ async fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("mounter - query and manage images mounted on a device. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"mounter - query and manage images mounted on a device. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{os_trace_relay::OsTraceRelayClient, IdeviceService};
|
use idevice::{IdeviceService, os_trace_relay::OsTraceRelayClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
|
IdeviceService,
|
||||||
lockdown::LockdownClient,
|
lockdown::LockdownClient,
|
||||||
usbmuxd::{Connection, UsbmuxdAddr, UsbmuxdConnection},
|
usbmuxd::{Connection, UsbmuxdAddr, UsbmuxdConnection},
|
||||||
IdeviceService,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake, IdeviceService, RsdService};
|
use idevice::{IdeviceService, RsdService, core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake, tcp::stream::AdapterStream,
|
IdeviceService, core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake,
|
||||||
IdeviceService,
|
tcp::stream::AdapterStream,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{
|
use idevice::{
|
||||||
core_device_proxy::CoreDeviceProxy, pretty_print_dictionary,
|
IdeviceService, RsdService, core_device_proxy::CoreDeviceProxy, pretty_print_dictionary,
|
||||||
restore_service::RestoreServiceClient, rsd::RsdHandshake, IdeviceService, RsdService,
|
restore_service::RestoreServiceClient, rsd::RsdHandshake,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
@@ -51,7 +51,9 @@ async fn main() {
|
|||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if matches.get_flag("about") {
|
if matches.get_flag("about") {
|
||||||
println!("mounter - query and manage images mounted on a device. Reimplementation of libimobiledevice's binary.");
|
println!(
|
||||||
|
"mounter - query and manage images mounted on a device. Reimplementation of libimobiledevice's binary."
|
||||||
|
);
|
||||||
println!("Copyright (c) 2025 Jackson Coxson");
|
println!("Copyright (c) 2025 Jackson Coxson");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use idevice::{syslog_relay::SyslogRelayClient, IdeviceService};
|
use idevice::{IdeviceService, syslog_relay::SyslogRelayClient};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user