Skip to content

Commit

Permalink
added new pipe command for reading an exact resource out an archive
Browse files Browse the repository at this point in the history
  • Loading branch information
sokorototo committed Mar 13, 2024
1 parent 34fa687 commit 567d9cc
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 21 deletions.
11 changes: 11 additions & 0 deletions vach-cli/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ pub fn build_app<'a>(key_map: HashMap<&'static str, Arg<'a>>) -> Command<'a> {
.arg(key_map.get(key_names::PUBLIC_KEY).unwrap())
.arg(key_map.get(key_names::TRUNCATE).unwrap()),
)
.subcommand(
Command::new("pipe")
.author(AUTHORS)
.version(commands::pipe::VERSION)
.about("Pipes the contents of a .vach archive to stdout")
.arg(key_map.get(key_names::INPUT).unwrap())
.arg(key_map.get(key_names::MAGIC).unwrap())
.arg(key_map.get(key_names::PUBLIC_KEY).unwrap())
.arg(key_map.get(key_names::RESOURCE).unwrap())
.arg(key_map.get(key_names::KEYPAIR).unwrap()),
)
.subcommand(
Command::new("pack")
.author(AUTHORS)
Expand Down
2 changes: 2 additions & 0 deletions vach-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub trait CommandTrait: Sync {
pub mod keypair;
pub mod list;
pub mod pack;
pub mod pipe;
pub mod split;
pub mod unpack;
pub mod verify;
Expand All @@ -28,6 +29,7 @@ pub fn build_commands() -> HashMap<&'static str, Box<dyn CommandTrait>> {
map.insert("list", Box::new(list::Evaluator));
map.insert("unpack", Box::new(unpack::Evaluator));
map.insert("pack", Box::new(pack::Evaluator));
map.insert("pipe", Box::new(pipe::Evaluator));

map
}
79 changes: 79 additions & 0 deletions vach-cli/src/commands/pipe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::{
fs::File,
io::{self, BufReader, Write},
};
use vach::{crypto_utils, prelude::*};

use super::CommandTrait;
use crate::keys::key_names;

pub const VERSION: &str = "0.1.0";

pub struct Evaluator;

impl CommandTrait for Evaluator {
fn evaluate(&self, args: &clap::ArgMatches) -> anyhow::Result<()> {
let input_path = match args.value_of(key_names::INPUT) {
Some(path) => path,
None => anyhow::bail!("Please provide an input path using the -i or --input key"),
};

let resource = match args.value_of(key_names::RESOURCE) {
Some(resource) => resource,
None => anyhow::bail!("Please provide a resource to extract using the -r or --resource key"),
};

let magic: [u8; vach::MAGIC_LENGTH] = match args.value_of(key_names::MAGIC) {
Some(magic) => magic.as_bytes().try_into()?,
None => *vach::DEFAULT_MAGIC,
};

// Attempting to extract a public key from a -p or -k input
let public_key = match args.value_of(key_names::KEYPAIR) {
Some(path) => {
let file = match File::open(path) {
Ok(it) => it,
Err(err) => anyhow::bail!("IOError: {} @ {}", err, path),
};

Some(crypto_utils::read_keypair(file)?.verifying_key())
},
None => match args.value_of(key_names::PUBLIC_KEY) {
Some(path) => {
let file = File::open(path)?;
Some(crypto_utils::read_public_key(file)?)
},
None => None,
},
};

let input_file = match File::open(input_path) {
Ok(it) => BufReader::new(it),
Err(err) => anyhow::bail!("IOError: {} @ {}", err, input_path),
};

// Generate ArchiveConfig using given magic and public key
let header_config = ArchiveConfig::new(magic, public_key);

// Parse then extract archive
let mut archive = match Archive::with_config(input_file, &header_config) {
Ok(archive) => archive,
Err(err) => match err {
InternalError::NoKeypairError => anyhow::bail!(
"Please provide a public key or a keypair for use in decryption or signature verification"
),
InternalError::MalformedArchiveSource(_) => anyhow::bail!("Unable to validate the archive: {}", err),
err => anyhow::bail!("Encountered an error: {}", err.to_string()),
},
};

let stdout = io::stdout();
{
let mut handle = stdout.lock();
let resource = archive.fetch_mut(resource)?;
handle.write_all(&resource.data)?;
}

Ok(())
}
}
4 changes: 2 additions & 2 deletions vach-cli/src/commands/unpack.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs::{self, File};
use std::str::FromStr;
use std::io::{Read, Seek, Write};
use std::io::{BufReader, Read, Seek, Write};
use std::path::PathBuf;
use std::time::Instant;

Expand Down Expand Up @@ -61,7 +61,7 @@ impl CommandTrait for Evaluator {
let truncate = args.is_present(key_names::TRUNCATE);

let input_file = match File::open(input_path) {
Ok(it) => it,
Ok(it) => BufReader::new(it),
Err(err) => anyhow::bail!("IOError: {} @ {}", err, input_path),
};

Expand Down
14 changes: 14 additions & 0 deletions vach-cli/src/keys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::collections::HashMap;
pub mod key_names {
pub(crate) const OUTPUT: &str = "OUTPUT";
pub(crate) const INPUT: &str = "INPUT";
pub(crate) const RESOURCE: &str = "RESOURCE";

pub(crate) const DIR_INPUT: &str = "DIR_INPUT";
pub(crate) const DIR_INPUT_REC: &str = "DIR_INPUT_REC";
Expand Down Expand Up @@ -45,6 +46,19 @@ pub fn build_keys<'a>() -> HashMap<&'static str, Arg<'a>> {
.number_of_values(1),
);

// A resource to focus on and extract
map.insert(
key_names::RESOURCE,
Arg::new(key_names::RESOURCE)
.short('r')
.long("resource")
.value_name(key_names::RESOURCE)
.help("An exact resource to extract from the archive")
.required(false)
.takes_value(true)
.number_of_values(1),
);

// A general input source
map.insert(
key_names::INPUT,
Expand Down
19 changes: 0 additions & 19 deletions vach-cli/src/keys/utils/mod.rs

This file was deleted.

0 comments on commit 567d9cc

Please sign in to comment.