diff --git a/src/cmd_info.rs b/src/cmd_info.rs new file mode 100644 index 0000000..a062ae3 --- /dev/null +++ b/src/cmd_info.rs @@ -0,0 +1,34 @@ +use std::fs::File; +use std::path::PathBuf; +use rust_util::{information, opt_result, simple_error, XResult}; +use crate::file; + +pub fn info(path: PathBuf) -> XResult<()> { + let path_display = format!("{}", path.display()); + let mut file_in = opt_result!(File::open(path), "Open file: {} failed: {}", &path_display); + let meta = opt_result!(file::read_tiny_encrypt_meta(&mut file_in), "Read file: {}, failed: {}", &path_display); + // println!("{}", serde_json::to_string_pretty(&meta).expect("SHOULD NOT HAPPEN")); + + let mut infos = vec![]; + infos.push("Tiny Encrypt File Info".to_string()); + infos.push(format!("File..............: {}", path_display)); + infos.push(format!("File size.........: {} bytes", meta.file_length)); + infos.push(format!("Enc file summary..: Version: {}, Agent: {}", meta.version, meta.user_agent)); + infos.push(format!("Last modified.....: {}", meta.file_last_modified)); + infos.push(format!("Enc file created..: {}", meta.created)); + infos.push(format!("Envelops..........: KMS: {}, PGP: {}", + to_yes_or_no(&meta.envelop), + to_yes_or_no(&meta.pgp_envelop) + )); + meta.pgp_fingerprint.map(|fingerprint| { + infos.push(format!("PGP fingerprint...: {}", fingerprint)); + }); + infos.push(format!("Encrypted comment.: {}", to_yes_or_no(&meta.encrypted_comment))); + + information!("{}\n", infos.join("\n")); + Ok(()) +} + +fn to_yes_or_no(opt: &Option) -> String { + opt.as_ref().map(|_| "YES".to_string()).unwrap_or_else(|| "NO".to_string()) +} \ No newline at end of file diff --git a/src/file.rs b/src/file.rs index 078b6d9..75b21e4 100644 --- a/src/file.rs +++ b/src/file.rs @@ -5,7 +5,7 @@ use rust_util::{opt_result, simple_error, XResult}; use crate::spec::TinyEncryptMeta; -fn write_tiny_encrypt_meta(w: &mut W, meta: &TinyEncryptMeta) -> XResult { +pub fn write_tiny_encrypt_meta(w: &mut W, meta: &TinyEncryptMeta) -> XResult { let meta_json = opt_result!( serde_json::to_string(meta), "Meta to JSON failed: {}"); let meta_json_bytes = meta_json.as_bytes(); let meta_json_bytes_len = meta_json_bytes.len(); @@ -17,7 +17,7 @@ fn write_tiny_encrypt_meta(w: &mut W, meta: &TinyEncryptMeta) -> XResu Ok(meta_json_bytes_len + 2 + 4) } -fn read_tiny_encrypt_meta(r: &mut R) -> XResult { +pub fn read_tiny_encrypt_meta(r: &mut R) -> XResult { let mut tag_buff = [0_u8; 2]; opt_result!(r.read_exact(&mut tag_buff), "Read tag failed: {}"); let tag = u16::from_be_bytes(tag_buff); @@ -32,8 +32,8 @@ fn read_tiny_encrypt_meta(r: &mut R) -> XResult { return simple_error!("Meta too large: {}", length); } - let mut meta_buff = Vec::with_capacity(length as usize); - opt_result!( r.read_exact(meta_buff.as_mut_slice()), "Read meta failed: {}"); + let mut meta_buff = vec![0; length as usize]; + opt_result!(r.read_exact(meta_buff.as_mut_slice()), "Read meta failed: {}"); Ok(opt_result!(serde_json::from_slice(&meta_buff), "Parse meta failed: {}")) } diff --git a/src/main.rs b/src/main.rs index 1ee32ba..0d4ab65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,15 @@ extern crate core; +use std::fs::File; use std::path::PathBuf; use clap::{Parser, Subcommand}; -use rust_util::information; +use rust_util::{information, XResult}; mod spec; mod crypto; mod file; +mod cmd_info; #[derive(Debug, Parser)] #[command(name = "tiny-encrypt-rs")] @@ -23,28 +25,33 @@ enum Commands { #[command(arg_required_else_help = true, short_flag = 'e')] Encrypt { /// Files need to be encrypted - files: Vec, + paths: Vec, }, /// Decrypt file(s) #[command(arg_required_else_help = true, short_flag = 'd')] Decrypt { /// Files need to be decrypted - files: Vec, + paths: Vec, }, /// Show file info #[command(arg_required_else_help = true, short_flag = 'I')] Info { - file: PathBuf, + path: PathBuf, }, } -fn main() { +fn main() -> XResult<()> { let args = Cli::parse(); match args.command { - Commands::Encrypt { files } => { - files.iter().for_each(|f| information!("{:?}", f)); + Commands::Encrypt { paths } => { + paths.iter().for_each(|f| information!("{:?}", f)); + Ok(()) + } + Commands::Decrypt { .. } => { + Ok(()) + } + Commands::Info { path } => { + cmd_info::info(path) } - Commands::Decrypt { .. } => todo!(), - Commands::Info { .. } => todo!() } } \ No newline at end of file diff --git a/src/spec.rs b/src/spec.rs index 54bd6e6..f59d406 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -16,7 +16,7 @@ pub struct TinyEncryptMeta { pub nonce: String, pub file_length: u64, pub file_last_modified: u64, - pub compress: Option, + pub compress: bool, } pub fn get_user_agent() -> String {