Rework reading from device and clean up.

This commit is contained in:
Olivia Brooks
2025-12-29 11:02:13 -05:00
parent 824d01be95
commit e08e2a0017
10 changed files with 628 additions and 536 deletions

View File

@@ -1,18 +1,16 @@
mod io;
mod mapping;
mod recovery;
use std::fs::{File, OpenOptions};
use std::path::{Path, PathBuf};
use clap::Parser;
use libc::O_DIRECT;
use mapping::MapFile;
use recovery::Recover;
use std::{
fs::{File, OpenOptions},
io::{self, Seek, SeekFrom},
os::unix::fs::OpenOptionsExt,
path::PathBuf,
};
const FB_SECTOR_SIZE: u16 = 2048;
const FB_PAD_VALUE: u8 = 0;
#[derive(Parser, Debug)]
struct Args {
@@ -48,35 +46,28 @@ fn main() {
// I'm lazy and don't want to mess around with comparing error types.
// Thus, any error in I/O here should be treated as fatal.
let mut input: File = {
match OpenOptions::new()
.custom_flags(O_DIRECT)
.read(true)
.open(&config.input.as_path())
{
Ok(f) => f,
Err(err) => panic!("Failed to open input file: {:?}", err),
}
};
let mut input: File = OpenOptions::new()
.read(true)
.open(&config.input.as_path())
.expect("Failed to open input file");
let mut output: File = {
let output: File = {
// Keep this clean, make a short-lived binding.
let path = get_path(&config.output, &config.input.to_str().unwrap(), "iso");
match OpenOptions::new()
.custom_flags(O_DIRECT)
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path)
{
Ok(f) => f,
Err(err) => panic!("Failed to open/create output file. {:?}", err),
}
.expect("Failed to open/create output file")
};
// Check if output file is shorter than input.
// If so, autoextend the output file.
//
// Is this actually needed? I don't think I need to preallocate the space.
/*
{
let input_len =
get_stream_length(&mut input).expect("Failed to get the length of the input data.");
@@ -89,14 +80,24 @@ fn main() {
.expect("Failed to autofill output file.")
}
}
*/
/*
let map: MapFile = {
let path = get_path(&config.output, &config.input.to_str().unwrap(), "map");
let path = get_path(
&config.output,
&config
.input
.to_str()
.expect("Input path is not UTF-8 valid"),
"map",
);
let file = match OpenOptions::new().read(true).create(true).open(path) {
Ok(f) => f,
Err(err) => panic!("Failed to open/create mapping file. {:?}", err),
};
let file = OpenOptions::new()
.read(true)
.create(true)
.open(path)
.expect("Failed to open/create mapping file");
if let Ok(map) = MapFile::try_from(file) {
map
@@ -104,37 +105,53 @@ fn main() {
MapFile::new(config.sector_size)
}
};
*/
let mut recover_tool = Recover::new(config, input, output, map);
let buf_capacity =
crate::io::get_stream_length(&mut input).expect("Failed to get buffer capacity from input");
let mut recover_tool = Recover::new(config, input, output, MapFile::default(), buf_capacity);
recover_tool.run();
todo!("Recovery, Map saving, and closure of all files.");
//todo!("Recovery, Map saving, and closure of all files.");
/*
let mut buf: Vec<u8> = Vec::with_capacity(
get_stream_length(&mut input).expect("Failed to get the length of the input data.")
as usize,
);
println!(
"Read {} bytes",
input
.read_to_end(&mut buf)
.expect("Failed to read complete input stream.")
);
println!("Wrote {} bytes", {
output
.write_all(&buf)
.expect("Failed to write complete output stream.");
&buf.len()
});
*/
}
/// Generates a file path if one not provided.
/// source_name for fallback name.
fn get_path(output: &Option<PathBuf>, source_name: &str, extension: &str) -> PathBuf {
if let Some(f) = output {
f.to_owned()
fn get_path<P>(file_path: &Option<P>, source_name: &str, extension: &str) -> PathBuf
where
P: AsRef<Path>,
{
if let Some(f) = file_path {
f.as_ref().to_path_buf()
} else {
PathBuf::from(format!("{:?}.{}", source_name, extension,))
PathBuf::from(format!("{:?}.{}", source_name, extension))
.as_path()
.to_owned()
}
}
/// Get length of data stream.
/// Physical length of data stream in bytes
/// (multiple of sector_size, rather than actual).
fn get_stream_length<S: Seek>(input: &mut S) -> io::Result<u64> {
let len = input.seek(SeekFrom::End(0))?;
let _ = input.seek(SeekFrom::Start(0));
Ok(len)
}
#[cfg(test)]
#[allow(unused)]
mod tests {