mirror of https://github.com/vinc/moros.git
Add hash command (#554)
* Add hash command * Fix globbing without dir * Add missing file
This commit is contained in:
parent
9086221bac
commit
ae6d47aec7
|
@ -0,0 +1,83 @@
|
|||
use crate::api;
|
||||
use crate::api::console::Style;
|
||||
use crate::api::process::ExitCode;
|
||||
use crate::api::syscall;
|
||||
|
||||
use alloc::format;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::str;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
pub fn main(args: &[&str]) -> Result<(), ExitCode> {
|
||||
let mut i = 1;
|
||||
let n = args.len();
|
||||
let mut paths = Vec::new();
|
||||
let mut full = false;
|
||||
while i < n {
|
||||
match args[i] {
|
||||
"-h" | "--help" => {
|
||||
help();
|
||||
return Ok(());
|
||||
}
|
||||
"-f" | "--full" => {
|
||||
full = true;
|
||||
}
|
||||
arg => {
|
||||
if arg.starts_with('-') {
|
||||
error!("Unknown option '{}'", arg);
|
||||
return Err(ExitCode::UsageError);
|
||||
}
|
||||
paths.push(arg);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
paths.sort();
|
||||
for path in paths {
|
||||
if let Err(code) = print_hash(path, full) {
|
||||
return Err(code);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_hash(path: &str, full: bool) -> Result<(), ExitCode> {
|
||||
let n = if full { 32 } else { 16 };
|
||||
if let Some(info) = syscall::info(path) {
|
||||
if info.is_file() {
|
||||
if let Ok(bytes) = api::fs::read_to_bytes(path) {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(bytes);
|
||||
let res = hasher.finalize();
|
||||
let hex = res.iter().map(|byte|
|
||||
format!("{:02X}", byte)
|
||||
).take(n).collect::<Vec<String>>().join("");
|
||||
let pink = Style::color("Pink");
|
||||
let reset = Style::reset();
|
||||
println!("{}{}{} {}", pink, hex, reset, path);
|
||||
Ok(())
|
||||
} else {
|
||||
error!("Could not read '{}'", path);
|
||||
Err(ExitCode::Failure)
|
||||
}
|
||||
} else {
|
||||
error!("Could not read '{}'", path);
|
||||
Err(ExitCode::Failure)
|
||||
}
|
||||
} else {
|
||||
error!("Could not find file '{}'", path);
|
||||
Err(ExitCode::Failure)
|
||||
}
|
||||
}
|
||||
|
||||
fn help() {
|
||||
let csi_option = Style::color("LightCyan");
|
||||
let csi_title = Style::color("Yellow");
|
||||
let csi_reset = Style::reset();
|
||||
println!("{}Usage:{} hash {}<file>{}", csi_title, csi_reset, csi_option, csi_reset);
|
||||
println!();
|
||||
println!("{}Options:{}", csi_title, csi_reset);
|
||||
println!(" {0}-f{1}, {0}--full{1} Show full hash", csi_option, csi_reset);
|
||||
}
|
|
@ -11,6 +11,7 @@ pub mod editor;
|
|||
pub mod elf;
|
||||
pub mod env;
|
||||
pub mod find;
|
||||
pub mod hash;
|
||||
pub mod help;
|
||||
pub mod hex;
|
||||
pub mod host;
|
||||
|
|
|
@ -14,11 +14,11 @@ use alloc::vec::Vec;
|
|||
use alloc::string::{String, ToString};
|
||||
|
||||
// TODO: Scan /bin
|
||||
const AUTOCOMPLETE_COMMANDS: [&str; 35] = [
|
||||
const AUTOCOMPLETE_COMMANDS: [&str; 36] = [
|
||||
"2048", "base64", "calc", "copy", "date", "delete", "dhcp", "disk", "edit", "elf", "env",
|
||||
"goto", "help", "hex", "host", "http", "httpd", "install", "keyboard", "life", "lisp",
|
||||
"list", "memory", "move", "net", "pci", "quit", "read", "shell", "socket", "tcp",
|
||||
"time", "user", "vga", "write"
|
||||
"goto", "hash", "help", "hex", "host", "http", "httpd", "install", "keyboard", "life", "lisp",
|
||||
"list", "memory", "move", "net", "pci", "quit", "read", "shell", "socket", "tcp", "time",
|
||||
"user", "vga", "write"
|
||||
];
|
||||
|
||||
struct Config {
|
||||
|
@ -142,10 +142,10 @@ fn glob_to_regex(pattern: &str) -> String {
|
|||
fn glob(arg: &str) -> Vec<String> {
|
||||
let mut matches = Vec::new();
|
||||
if is_globbing(arg) {
|
||||
let (dir, pattern) = if arg.contains('/') {
|
||||
(fs::dirname(arg).to_string(), fs::filename(arg).to_string())
|
||||
let (dir, pattern, show_dir) = if arg.contains('/') {
|
||||
(fs::dirname(arg).to_string(), fs::filename(arg).to_string(), true)
|
||||
} else {
|
||||
(sys::process::dir(), arg.to_string())
|
||||
(sys::process::dir(), arg.to_string(), false)
|
||||
};
|
||||
|
||||
let re = Regex::new(&glob_to_regex(&pattern));
|
||||
|
@ -155,7 +155,11 @@ fn glob(arg: &str) -> Vec<String> {
|
|||
for file in files {
|
||||
let name = file.name();
|
||||
if re.is_match(&name) {
|
||||
matches.push(format!("{}{}{}", dir, sep, name));
|
||||
if show_dir {
|
||||
matches.push(format!("{}{}{}", dir, sep, name));
|
||||
} else {
|
||||
matches.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -454,6 +458,7 @@ fn exec_with_config(cmd: &str, config: &mut Config) -> Result<(), ExitCode> {
|
|||
"env" => usr::env::main(&args),
|
||||
"find" => usr::find::main(&args),
|
||||
"goto" => cmd_change_dir(&args, config), // TODO: Remove this
|
||||
"hash" => usr::hash::main(&args),
|
||||
"help" => usr::help::main(&args),
|
||||
"hex" => usr::hex::main(&args),
|
||||
"host" => usr::host::main(&args),
|
||||
|
|
Loading…
Reference in New Issue