feat: add basic dd
This commit is contained in:
parent
8774468d48
commit
e2e038fc18
3 changed files with 89 additions and 0 deletions
85
coreutils/src/commands/dd.rs
Normal file
85
coreutils/src/commands/dd.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
use boxutils::commands::Command;
|
||||||
|
use std::env;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::io::{self, Read, Write, BufReader};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
pub struct Dd;
|
||||||
|
|
||||||
|
impl Command for Dd {
|
||||||
|
fn execute(&self) {
|
||||||
|
// dd has its seperate argument parsing
|
||||||
|
let mut arguments = HashMap::new();
|
||||||
|
let mut blocksize = 512;
|
||||||
|
|
||||||
|
for argument in env::args() {
|
||||||
|
if let Some((k, v)) = argument.split_once('=') {
|
||||||
|
arguments.insert(k.to_string().to_lowercase(), v.to_string());
|
||||||
|
} // don't handle anything that does not follow dd's syntax.
|
||||||
|
// TODO: inform about malformed arguments
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(bs) = arguments.get("bs") {
|
||||||
|
let (k, v) = bs.split_at(bs.len() - 1);
|
||||||
|
if v.parse::<u64>().is_ok() {
|
||||||
|
// assume the bs is specified in bytes,
|
||||||
|
// because the last char is a number
|
||||||
|
blocksize = bs.parse::<u64>().unwrap()
|
||||||
|
} else {
|
||||||
|
match v {
|
||||||
|
"K" | "k" => blocksize = k.parse::<u64>().unwrap() * 1024,
|
||||||
|
"M" => blocksize = k.parse::<u64>().unwrap() * 1024 * 1024,
|
||||||
|
"G" => blocksize = k.parse::<u64>().unwrap() * 1024 * 1024 * 1024,
|
||||||
|
"kB" => blocksize = k.parse::<u64>().unwrap() * 1000,
|
||||||
|
"MB" => blocksize = k.parse::<u64>().unwrap() * 1000 * 1000,
|
||||||
|
"GB" => blocksize = k.parse::<u64>().unwrap() * 1000 * 1000 * 1000,
|
||||||
|
_ => {
|
||||||
|
eprintln!("Invalid blocksize specified.");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut vecbuf = Vec::with_capacity(blocksize.try_into().unwrap());
|
||||||
|
let start = Instant::now();
|
||||||
|
|
||||||
|
if let Some(input) = arguments.get("if") {
|
||||||
|
let mut f = BufReader::new(File::open(input).unwrap());
|
||||||
|
let _ = f.read_to_end(&mut vecbuf).unwrap();
|
||||||
|
} else {
|
||||||
|
let _ = io::stdin().read_to_end(&mut vecbuf).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(output) = arguments.get("of") {
|
||||||
|
let buffer = File::create(output);
|
||||||
|
let _ = buffer.unwrap().write(&vecbuf);
|
||||||
|
} else {
|
||||||
|
let _ = io::stdout().write_all(&vecbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
let duration = start.elapsed().as_millis() / 1000;
|
||||||
|
|
||||||
|
let out_blocks = vecbuf.len() as u64 / blocksize;
|
||||||
|
let out_remainder = vecbuf.len() as u64 % blocksize;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}+{} records in", // TODO: actually calculate records in
|
||||||
|
out_blocks,
|
||||||
|
out_remainder
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}+{} records out",
|
||||||
|
out_blocks,
|
||||||
|
out_remainder
|
||||||
|
);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{} bytes copied, ca. {} seconds",
|
||||||
|
vecbuf.len(),
|
||||||
|
duration
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,3 +9,6 @@ pub use echo::Echo;
|
||||||
|
|
||||||
mod mkdir;
|
mod mkdir;
|
||||||
pub use mkdir::Mkdir;
|
pub use mkdir::Mkdir;
|
||||||
|
|
||||||
|
mod dd;
|
||||||
|
pub use dd::Dd;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ pub fn get_registry() -> CommandRegistry {
|
||||||
registry.register("echo", Box::new(coreutils::commands::Echo));
|
registry.register("echo", Box::new(coreutils::commands::Echo));
|
||||||
registry.register("mkdir", Box::new(coreutils::commands::Mkdir));
|
registry.register("mkdir", Box::new(coreutils::commands::Mkdir));
|
||||||
registry.register("ash", Box::new(shell::ash::Ash));
|
registry.register("ash", Box::new(shell::ash::Ash));
|
||||||
|
registry.register("dd", Box::new(coreutils::commands::Dd));
|
||||||
registry.register("box", Box::new(Boxcmd));
|
registry.register("box", Box::new(Boxcmd));
|
||||||
|
|
||||||
registry
|
registry
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue