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,
fs::File,
str::FromStr,
io::{stdin, stdout, Read, Write},
io::{stdin, stdout, Read},
};
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");
@ -16,7 +16,7 @@ pub struct CliArgs {
pub cipher: CipherAlgorithm,
pub block_size: usize,
pub reader: Box<dyn Read>,
pub writer: Box<dyn Write>,
pub writer: LazyWriter<String>,
}
pub fn parse() -> Option<CliArgs> {
@ -133,10 +133,10 @@ pub fn parse() -> Option<CliArgs> {
eprintln!("WARNING: {} already exists", s);
None
} 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 {
password: app.value_of("1_password").into(),

View File

@ -1,7 +1,7 @@
pub mod cli;
pub mod crypto;
use std::io::{self, Read, Write};
use std::{fs::File, path::Path, io::{self, Read, Write}};
use crypto::{DobyCipher, EncryptionParams};
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<()> {
writer.write_all(MAGIC_BYTES)?;
params.write(writer)?;