afc write file

This commit is contained in:
Jackson Coxson
2025-04-06 11:53:45 -06:00
parent 7b0590b7ae
commit 1a7534a106
2 changed files with 55 additions and 3 deletions

View File

@@ -22,7 +22,7 @@ impl FileDescriptor<'_> {
let header = AfcPacketHeader { let header = AfcPacketHeader {
magic: super::MAGIC, magic: super::MAGIC,
entire_len: header_len, // it's the same since the payload is empty for this entire_len: header_len,
header_payload_len: header_len, header_payload_len: header_len,
packet_num: self.client.package_number, packet_num: self.client.package_number,
operation: AfcOpcode::FileClose, operation: AfcOpcode::FileClose,
@@ -52,7 +52,7 @@ impl FileDescriptor<'_> {
let header = AfcPacketHeader { let header = AfcPacketHeader {
magic: super::MAGIC, magic: super::MAGIC,
entire_len: header_len, // it's the same since the payload is empty for this entire_len: header_len,
header_payload_len: header_len, header_payload_len: header_len,
packet_num: self.client.package_number, packet_num: self.client.package_number,
operation: AfcOpcode::Read, operation: AfcOpcode::Read,
@@ -73,4 +73,32 @@ impl FileDescriptor<'_> {
Ok(collected_bytes) Ok(collected_bytes)
} }
pub async fn write(&mut self, bytes: &[u8]) -> Result<(), IdeviceError> {
let chunks = bytes.chunks(MAX_TRANSFER as usize);
for chunk in chunks {
let header_payload = self.fd.to_le_bytes().to_vec();
let header_len = header_payload.len() as u64 + AfcPacketHeader::LEN;
let header = AfcPacketHeader {
magic: super::MAGIC,
entire_len: header_len + chunk.len() as u64,
header_payload_len: header_len,
packet_num: self.client.package_number,
operation: AfcOpcode::Write,
};
self.client.package_number += 1;
let packet = AfcPacket {
header,
header_payload,
payload: chunk.to_vec(),
};
self.client.send(packet).await?;
self.client.read().await?;
}
Ok(())
}
} }

View File

@@ -1,6 +1,8 @@
// Jackson Coxson // Jackson Coxson
use clap::{Arg, Command}; use std::path::PathBuf;
use clap::{value_parser, Arg, Command};
use idevice::{ use idevice::{
afc::{opcode::AfcFopenMode, AfcClient}, afc::{opcode::AfcFopenMode, AfcClient},
IdeviceService, IdeviceService,
@@ -48,6 +50,17 @@ async fn main() {
.arg(Arg::new("path").required(true).index(1)) .arg(Arg::new("path").required(true).index(1))
.arg(Arg::new("save").required(true).index(2)), .arg(Arg::new("save").required(true).index(2)),
) )
.subcommand(
Command::new("upload")
.about("Creates a directory")
.arg(
Arg::new("file")
.required(true)
.index(1)
.value_parser(value_parser!(PathBuf)),
)
.arg(Arg::new("path").required(true).index(2)),
)
.subcommand( .subcommand(
Command::new("mkdir") Command::new("mkdir")
.about("Creates a directory") .about("Creates a directory")
@@ -112,6 +125,17 @@ async fn main() {
tokio::fs::write(save, res) tokio::fs::write(save, res)
.await .await
.expect("Failed to write to file"); .expect("Failed to write to file");
} else if let Some(matches) = matches.subcommand_matches("upload") {
let file = matches.get_one::<PathBuf>("file").expect("No path passed");
let path = matches.get_one::<String>("path").expect("No path passed");
let bytes = tokio::fs::read(file).await.expect("Failed to read file");
let mut file = afc_client
.open(path, AfcFopenMode::WrOnly)
.await
.expect("Failed to open");
file.write(&bytes).await.expect("Failed to upload bytes");
} else if let Some(matches) = matches.subcommand_matches("remove") { } else if let Some(matches) = matches.subcommand_matches("remove") {
let path = matches.get_one::<String>("path").expect("No path passed"); let path = matches.get_one::<String>("path").expect("No path passed");
afc_client.remove(path).await.expect("Failed to remove"); afc_client.remove(path).await.expect("Failed to remove");