Create output file only when writing

This commit is contained in:
Matéo Duparc 2021-07-04 19:24:20 +02:00
parent 219e431fbd
commit b4839b95c7
Signed by: hardcoresushi
GPG Key ID: 007F84120107191E
2 changed files with 39 additions and 6 deletions

View File

@ -2,10 +2,10 @@ use std::{
path::Path, path::Path,
fs::File, fs::File,
str::FromStr, str::FromStr,
io::{stdin, stdout, Read, Write}, io::{stdin, stdout, Read},
}; };
use clap::{crate_name, crate_version, App, Arg, AppSettings}; use clap::{crate_name, crate_version, App, Arg, AppSettings};
use crate::{Password, crypto::{ArgonParams, CipherAlgorithm}}; use crate::{LazyWriter, Password, crypto::{ArgonParams, CipherAlgorithm}};
cpufeatures::new!(aes_ni, "aes"); cpufeatures::new!(aes_ni, "aes");
@ -16,7 +16,7 @@ pub struct CliArgs {
pub cipher: CipherAlgorithm, pub cipher: CipherAlgorithm,
pub block_size: usize, pub block_size: usize,
pub reader: Box<dyn Read>, pub reader: Box<dyn Read>,
pub writer: Box<dyn Write>, pub writer: LazyWriter<String>,
} }
pub fn parse() -> Option<CliArgs> { pub fn parse() -> Option<CliArgs> {
@ -133,10 +133,10 @@ pub fn parse() -> Option<CliArgs> {
eprintln!("WARNING: {} already exists", s); eprintln!("WARNING: {} already exists", s);
None None
} else { } else {
Some(Box::new(File::create(s).unwrap()) as Box<dyn Write>) Some(LazyWriter::from_path(s.to_owned()))
} }
}) })
.unwrap_or_else(|| Some(Box::new(stdout())))?; .unwrap_or_else(|| Some(LazyWriter::from_writer(stdout())))?;
Some(CliArgs { Some(CliArgs {
password: app.value_of("1_password").into(), password: app.value_of("1_password").into(),

View File

@ -1,7 +1,7 @@
pub mod cli; pub mod cli;
pub mod crypto; pub mod crypto;
use std::io::{self, Read, Write}; use std::{fs::File, path::Path, io::{self, Read, Write}};
use crypto::{DobyCipher, EncryptionParams}; use crypto::{DobyCipher, EncryptionParams};
use zeroize::Zeroize; use zeroize::Zeroize;
@ -33,6 +33,39 @@ impl Zeroize for Password {
} }
} }
pub struct LazyWriter<P: AsRef<Path>> {
path: Option<P>,
writer: Option<Box<dyn Write>>,
}
impl<P: AsRef<Path>> LazyWriter<P> {
fn from_path(path: P) -> Self {
Self {
path: Some(path),
writer: None,
}
}
fn from_writer<T: 'static + Write>(writer: T) -> Self {
Self {
path: None,
writer: Some(Box::new(writer)),
}
}
}
impl<P: AsRef<Path>> Write for LazyWriter<P> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if self.writer.is_none() {
self.writer = Some(Box::new(File::create(self.path.as_ref().unwrap()).unwrap()));
}
self.writer.as_mut().unwrap().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.writer.as_mut().unwrap().flush()
}
}
pub fn encrypt<R: Read, W: Write>(reader: &mut R, writer: &mut W, params: &EncryptionParams, mut cipher: DobyCipher, block_size: usize, already_read: Option<Vec<u8>>) -> io::Result<()> { pub fn encrypt<R: Read, W: Write>(reader: &mut R, writer: &mut W, params: &EncryptionParams, mut cipher: DobyCipher, block_size: usize, already_read: Option<Vec<u8>>) -> io::Result<()> {
writer.write_all(MAGIC_BYTES)?; writer.write_all(MAGIC_BYTES)?;
params.write(writer)?; params.write(writer)?;