mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-24 14:46:53 +01:00
little cleanup
This commit is contained in:
parent
3b54b6f8bc
commit
802e882b13
@ -874,126 +874,123 @@ fn handle_sd_command(connection: Connection, command: &SDCommands) -> Result<(),
|
|||||||
|
|
||||||
sc64.reset_state()?;
|
sc64.reset_state()?;
|
||||||
|
|
||||||
sc64::ff::run(sc64, |ff| {
|
let mut ff = sc64::ff::FatFs::new(sc64)?;
|
||||||
match command {
|
|
||||||
SDCommands::List { path } => {
|
match command {
|
||||||
for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? {
|
SDCommands::List { path } => {
|
||||||
let sc64::ff::Entry {
|
for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? {
|
||||||
info,
|
|
||||||
datetime,
|
|
||||||
name,
|
|
||||||
} = item;
|
|
||||||
let name = match info {
|
|
||||||
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
|
|
||||||
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
|
|
||||||
};
|
|
||||||
println!("{info} {datetime} | {}", name.bold());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDCommands::Stat { path } => {
|
|
||||||
let sc64::ff::Entry {
|
let sc64::ff::Entry {
|
||||||
info,
|
info,
|
||||||
datetime,
|
datetime,
|
||||||
name,
|
name,
|
||||||
} = ff.stat(path)?;
|
} = item;
|
||||||
let name = match info {
|
let name = match info {
|
||||||
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
|
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
|
||||||
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
|
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
|
||||||
};
|
};
|
||||||
println!("{info} {datetime} | {}", name.bold());
|
println!("{info} {datetime} | {}", name.bold());
|
||||||
}
|
}
|
||||||
SDCommands::Move { src, dst } => {
|
}
|
||||||
ff.rename(src, dst)?;
|
SDCommands::Stat { path } => {
|
||||||
println!(
|
let sc64::ff::Entry {
|
||||||
"Successfully moved {} to {}",
|
info,
|
||||||
|
datetime,
|
||||||
|
name,
|
||||||
|
} = ff.stat(path)?;
|
||||||
|
let name = match info {
|
||||||
|
sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(),
|
||||||
|
sc64::ff::EntryInfo::File { size: _ } => name.bright_green(),
|
||||||
|
};
|
||||||
|
println!("{info} {datetime} | {}", name.bold());
|
||||||
|
}
|
||||||
|
SDCommands::Move { src, dst } => {
|
||||||
|
ff.rename(src, dst)?;
|
||||||
|
println!(
|
||||||
|
"Successfully moved {} to {}",
|
||||||
|
src.to_str().unwrap_or_default().bright_green(),
|
||||||
|
dst.to_str().unwrap_or_default().bright_green()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SDCommands::Delete { path } => {
|
||||||
|
ff.delete(path)?;
|
||||||
|
println!(
|
||||||
|
"Successfully deleted {}",
|
||||||
|
path.to_str().unwrap_or_default().bright_green()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SDCommands::CreateDirectory { path } => {
|
||||||
|
ff.mkdir(path)?;
|
||||||
|
println!(
|
||||||
|
"Successfully created {}",
|
||||||
|
path.to_str().unwrap_or_default().bright_green()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SDCommands::Download { src, dst } => {
|
||||||
|
let dst = &dst.clone().unwrap_or(
|
||||||
|
src.file_name()
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.ok_or(sc64::ff::Error::InvalidParameter)?,
|
||||||
|
);
|
||||||
|
let mut src_file = ff.open(src)?;
|
||||||
|
let mut dst_file = std::fs::File::create(dst)?;
|
||||||
|
let mut buffer = vec![0; 128 * 1024];
|
||||||
|
log_wait(
|
||||||
|
format!(
|
||||||
|
"Downloading {} to {}",
|
||||||
src.to_str().unwrap_or_default().bright_green(),
|
src.to_str().unwrap_or_default().bright_green(),
|
||||||
dst.to_str().unwrap_or_default().bright_green()
|
dst.to_str().unwrap_or_default().bright_green()
|
||||||
);
|
),
|
||||||
}
|
|| loop {
|
||||||
SDCommands::Delete { path } => {
|
|
||||||
ff.delete(path)?;
|
|
||||||
println!(
|
|
||||||
"Successfully deleted {}",
|
|
||||||
path.to_str().unwrap_or_default().bright_green()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
SDCommands::CreateDirectory { path } => {
|
|
||||||
ff.mkdir(path)?;
|
|
||||||
println!(
|
|
||||||
"Successfully created {}",
|
|
||||||
path.to_str().unwrap_or_default().bright_green()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
SDCommands::Download { src, dst } => {
|
|
||||||
let dst = &dst.clone().unwrap_or(
|
|
||||||
src.file_name()
|
|
||||||
.map(PathBuf::from)
|
|
||||||
.ok_or(sc64::ff::Error::InvalidParameter)?,
|
|
||||||
);
|
|
||||||
let mut src_file = ff.open(src)?;
|
|
||||||
let mut dst_file = std::fs::File::create(dst)?;
|
|
||||||
let mut buffer = vec![0; 128 * 1024];
|
|
||||||
print!(
|
|
||||||
"{}",
|
|
||||||
format!(
|
|
||||||
"Downloading {} to {}... ",
|
|
||||||
src.to_str().unwrap_or_default().bright_green(),
|
|
||||||
dst.to_str().unwrap_or_default().bright_green()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
stdout().flush().unwrap();
|
|
||||||
loop {
|
|
||||||
match src_file.read(&mut buffer)? {
|
match src_file.read(&mut buffer)? {
|
||||||
0 => break,
|
0 => return Ok(()),
|
||||||
bytes => dst_file.write_all(&buffer[0..bytes])?,
|
bytes => {
|
||||||
|
if let Err(e) = dst_file.write_all(&buffer[0..bytes]) {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
println!("{}", "done!".bright_green());
|
)?;
|
||||||
}
|
|
||||||
SDCommands::Upload { src, dst } => {
|
|
||||||
let dst = &dst.clone().unwrap_or(
|
|
||||||
src.file_name()
|
|
||||||
.map(PathBuf::from)
|
|
||||||
.ok_or(sc64::ff::Error::InvalidParameter)?,
|
|
||||||
);
|
|
||||||
let mut src_file = std::fs::File::open(src)?;
|
|
||||||
let mut dst_file = ff.create(dst)?;
|
|
||||||
let mut buffer = vec![0; 128 * 1024];
|
|
||||||
print!(
|
|
||||||
"{}",
|
|
||||||
format!(
|
|
||||||
"Uploading {} to {}... ",
|
|
||||||
src.to_str().unwrap_or_default().bright_green(),
|
|
||||||
dst.to_str().unwrap_or_default().bright_green()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
stdout().flush().unwrap();
|
|
||||||
loop {
|
|
||||||
match src_file.read(&mut buffer)? {
|
|
||||||
0 => break,
|
|
||||||
bytes => dst_file.write_all(&buffer[0..bytes])?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("{}", "done!".bright_green());
|
|
||||||
}
|
|
||||||
SDCommands::Format => {
|
|
||||||
let answer = prompt(format!(
|
|
||||||
"{}",
|
|
||||||
"Do you really want to format the SD card? [y/N] ".bold()
|
|
||||||
));
|
|
||||||
if answer.to_ascii_lowercase() != "y" {
|
|
||||||
println!("{}", "Format operation aborted".red());
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
print!("Formatting the SD card... ",);
|
|
||||||
stdout().flush().unwrap();
|
|
||||||
ff.mkfs()?;
|
|
||||||
println!("{}", "done!".bright_green());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
SDCommands::Upload { src, dst } => {
|
||||||
Ok(())
|
let dst = &dst.clone().unwrap_or(
|
||||||
})?;
|
src.file_name()
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.ok_or(sc64::ff::Error::InvalidParameter)?,
|
||||||
|
);
|
||||||
|
let mut src_file = std::fs::File::open(src)?;
|
||||||
|
let mut dst_file = ff.create(dst)?;
|
||||||
|
let mut buffer = vec![0; 128 * 1024];
|
||||||
|
log_wait(
|
||||||
|
format!(
|
||||||
|
"Uploading {} to {}",
|
||||||
|
src.to_str().unwrap_or_default().bright_green(),
|
||||||
|
dst.to_str().unwrap_or_default().bright_green()
|
||||||
|
),
|
||||||
|
|| loop {
|
||||||
|
match src_file.read(&mut buffer)? {
|
||||||
|
0 => return Ok(()),
|
||||||
|
bytes => {
|
||||||
|
if let Err(e) = dst_file.write_all(&buffer[0..bytes]) {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
SDCommands::Format => {
|
||||||
|
let answer = prompt(format!(
|
||||||
|
"{}",
|
||||||
|
"Do you really want to format the SD card? [y/N] ".bold()
|
||||||
|
));
|
||||||
|
if answer.to_ascii_lowercase() != "y" {
|
||||||
|
println!("{}", "Format operation aborted".red());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
log_wait(format!("Formatting the SD card"), || ff.mkfs())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -120,121 +120,6 @@ pub type Error = fatfs::Error;
|
|||||||
|
|
||||||
static mut DRIVER: std::sync::Mutex<Option<Box<dyn FFDriver>>> = std::sync::Mutex::new(None);
|
static mut DRIVER: std::sync::Mutex<Option<Box<dyn FFDriver>>> = std::sync::Mutex::new(None);
|
||||||
|
|
||||||
pub struct FF {
|
|
||||||
fs: Box<fatfs::FATFS>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FF {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
fs: Box::new(unsafe { std::mem::zeroed() }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mount(&mut self) -> Result<(), Error> {
|
|
||||||
match unsafe { fatfs::f_mount(&mut *self.fs, fatfs::path("")?.as_ptr(), 0) } {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unmount(&self) -> Result<(), Error> {
|
|
||||||
match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn open<P: AsRef<std::path::Path>>(&self, path: P) -> Result<File, Error> {
|
|
||||||
File::open(
|
|
||||||
path,
|
|
||||||
fatfs::FA_OPEN_EXISTING | fatfs::FA_READ | fatfs::FA_WRITE,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create<P: AsRef<std::path::Path>>(&self, path: P) -> Result<File, Error> {
|
|
||||||
File::open(
|
|
||||||
path,
|
|
||||||
fatfs::FA_CREATE_ALWAYS | fatfs::FA_READ | fatfs::FA_WRITE,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stat<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Entry, Error> {
|
|
||||||
let mut fno = unsafe { std::mem::zeroed() };
|
|
||||||
match unsafe { fatfs::f_stat(fatfs::path(path)?.as_ptr(), &mut fno) } {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(fno.into()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn opendir<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Directory, Error> {
|
|
||||||
Directory::open(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Vec<Entry>, Error> {
|
|
||||||
let mut dir = self.opendir(path)?;
|
|
||||||
|
|
||||||
let mut list = vec![];
|
|
||||||
|
|
||||||
while let Some(entry) = dir.read()? {
|
|
||||||
list.push(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
list.sort_by_key(|k| (k.info, k.name.to_lowercase()));
|
|
||||||
|
|
||||||
Ok(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mkdir<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), Error> {
|
|
||||||
match unsafe { fatfs::f_mkdir(fatfs::path(path)?.as_ptr()) } {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), Error> {
|
|
||||||
match unsafe { fatfs::f_unlink(fatfs::path(path)?.as_ptr()) } {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rename<P: AsRef<std::path::Path>>(&self, old: P, new: P) -> Result<(), Error> {
|
|
||||||
match unsafe { fatfs::f_rename(fatfs::path(old)?.as_ptr(), fatfs::path(new)?.as_ptr()) } {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mkfs(&self) -> Result<(), Error> {
|
|
||||||
let mut work = [0u8; 16 * 1024];
|
|
||||||
match unsafe {
|
|
||||||
fatfs::f_mkfs(
|
|
||||||
fatfs::path("")?.as_ptr(),
|
|
||||||
std::ptr::null(),
|
|
||||||
work.as_mut_ptr().cast(),
|
|
||||||
size_of_val(&work) as u32,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
fatfs::FRESULT_FR_OK => Ok(()),
|
|
||||||
error => Err(error.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run<F: FnOnce(&mut FF) -> Result<(), super::Error>>(
|
|
||||||
driver: impl FFDriver + 'static,
|
|
||||||
runner: F,
|
|
||||||
) -> Result<(), super::Error> {
|
|
||||||
install_driver(driver)?;
|
|
||||||
let mut ff = FF::new();
|
|
||||||
ff.mount()?;
|
|
||||||
let result = runner(&mut ff);
|
|
||||||
ff.unmount().ok();
|
|
||||||
uninstall_driver().ok();
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn install_driver(driver: impl FFDriver + 'static) -> Result<(), Error> {
|
fn install_driver(driver: impl FFDriver + 'static) -> Result<(), Error> {
|
||||||
let mut d = unsafe { DRIVER.lock().unwrap() };
|
let mut d = unsafe { DRIVER.lock().unwrap() };
|
||||||
if d.is_some() {
|
if d.is_some() {
|
||||||
@ -253,6 +138,119 @@ fn uninstall_driver() -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FatFs {
|
||||||
|
fs: Box<fatfs::FATFS>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FatFs {
|
||||||
|
pub fn new(driver: impl FFDriver + 'static) -> Result<Self, Error> {
|
||||||
|
install_driver(driver)?;
|
||||||
|
let mut ff = Self {
|
||||||
|
fs: Box::new(unsafe { std::mem::zeroed() }),
|
||||||
|
};
|
||||||
|
ff.mount(false)?;
|
||||||
|
Ok(ff)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mount(&mut self, force: bool) -> Result<(), Error> {
|
||||||
|
let opt = if force { 1 } else { 0 };
|
||||||
|
match unsafe { fatfs::f_mount(&mut *self.fs, fatfs::path("")?.as_ptr(), opt) } {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmount(&mut self) -> Result<(), Error> {
|
||||||
|
match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<File, Error> {
|
||||||
|
File::open(
|
||||||
|
path,
|
||||||
|
fatfs::FA_OPEN_EXISTING | fatfs::FA_READ | fatfs::FA_WRITE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<File, Error> {
|
||||||
|
File::open(
|
||||||
|
path,
|
||||||
|
fatfs::FA_CREATE_ALWAYS | fatfs::FA_READ | fatfs::FA_WRITE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stat<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<Entry, Error> {
|
||||||
|
let mut fno = unsafe { std::mem::zeroed() };
|
||||||
|
match unsafe { fatfs::f_stat(fatfs::path(path)?.as_ptr(), &mut fno) } {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(fno.into()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opendir<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<Directory, Error> {
|
||||||
|
Directory::open(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<Vec<Entry>, Error> {
|
||||||
|
let mut dir = self.opendir(path)?;
|
||||||
|
|
||||||
|
let mut list = vec![];
|
||||||
|
|
||||||
|
while let Some(entry) = dir.read()? {
|
||||||
|
list.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
list.sort_by_key(|k| (k.info, k.name.to_lowercase()));
|
||||||
|
|
||||||
|
Ok(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mkdir<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), Error> {
|
||||||
|
match unsafe { fatfs::f_mkdir(fatfs::path(path)?.as_ptr()) } {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), Error> {
|
||||||
|
match unsafe { fatfs::f_unlink(fatfs::path(path)?.as_ptr()) } {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rename<P: AsRef<std::path::Path>>(&mut self, old: P, new: P) -> Result<(), Error> {
|
||||||
|
match unsafe { fatfs::f_rename(fatfs::path(old)?.as_ptr(), fatfs::path(new)?.as_ptr()) } {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mkfs(&mut self) -> Result<(), Error> {
|
||||||
|
let mut work = [0u8; 16 * 1024];
|
||||||
|
match unsafe {
|
||||||
|
fatfs::f_mkfs(
|
||||||
|
fatfs::path("")?.as_ptr(),
|
||||||
|
std::ptr::null(),
|
||||||
|
work.as_mut_ptr().cast(),
|
||||||
|
size_of_val(&work) as u32,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
fatfs::FRESULT_FR_OK => Ok(()),
|
||||||
|
error => Err(error.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FatFs {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.unmount().ok();
|
||||||
|
uninstall_driver().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum IOCtl {
|
pub enum IOCtl {
|
||||||
Sync,
|
Sync,
|
||||||
GetSectorCount(fatfs::LBA_t),
|
GetSectorCount(fatfs::LBA_t),
|
||||||
|
Loading…
Reference in New Issue
Block a user