mirror of
https://github.com/xavo95/repak.git
synced 2025-01-31 06:59:35 +00:00
add encryption feature
This commit is contained in:
parent
079693af22
commit
aae65c12cf
5 changed files with 147 additions and 23 deletions
|
@ -7,13 +7,14 @@ version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["compression"]
|
default = ["compression", "encryption"]
|
||||||
compression = ["dep:flate2", "dep:zstd"]
|
compression = ["dep:flate2", "dep:zstd"]
|
||||||
oodle = ["dep:libloading", "dep:ureq", "dep:once_cell", "dep:hex-literal", "dep:hex"]
|
oodle = ["dep:libloading", "dep:ureq", "dep:once_cell", "dep:hex-literal", "dep:hex"]
|
||||||
|
encryption = ["dep:aes"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.4"
|
byteorder = "1.4"
|
||||||
aes = "0.8"
|
aes = { version = "0.8", optional = true }
|
||||||
flate2 = { version = "1.0", optional = true }
|
flate2 = { version = "1.0", optional = true }
|
||||||
zstd = { version = "0.12", optional = true }
|
zstd = { version = "0.12", optional = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
|
@ -311,17 +311,22 @@ impl Entry {
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: Version,
|
version: Version,
|
||||||
compression: &[Compression],
|
compression: &[Compression],
|
||||||
key: Option<&aes::Aes256>,
|
#[cfg(feature = "encryption")] key: Option<&aes::Aes256>,
|
||||||
buf: &mut W,
|
buf: &mut W,
|
||||||
) -> Result<(), super::Error> {
|
) -> Result<(), super::Error> {
|
||||||
reader.seek(io::SeekFrom::Start(self.offset))?;
|
reader.seek(io::SeekFrom::Start(self.offset))?;
|
||||||
Entry::read(reader, version)?;
|
Entry::read(reader, version)?;
|
||||||
let data_offset = reader.stream_position()?;
|
let data_offset = reader.stream_position()?;
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut data = reader.read_len(match self.is_encrypted() {
|
let mut data = reader.read_len(match self.is_encrypted() {
|
||||||
true => align(self.compressed),
|
true => align(self.compressed),
|
||||||
false => self.compressed,
|
false => self.compressed,
|
||||||
} as usize)?;
|
} as usize)?;
|
||||||
if self.is_encrypted() {
|
if self.is_encrypted() {
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
|
return Err(super::Error::Encryption);
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
{
|
||||||
let Some(key) = key else {
|
let Some(key) = key else {
|
||||||
return Err(super::Error::Encrypted);
|
return Err(super::Error::Encrypted);
|
||||||
};
|
};
|
||||||
|
@ -331,6 +336,7 @@ impl Entry {
|
||||||
}
|
}
|
||||||
data.truncate(self.compressed as usize);
|
data.truncate(self.compressed as usize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ranges = match &self.blocks {
|
let ranges = match &self.blocks {
|
||||||
Some(blocks) => blocks
|
Some(blocks) => blocks
|
||||||
|
|
|
@ -13,6 +13,9 @@ pub enum Error {
|
||||||
#[error("enable the compression feature to read compressed paks")]
|
#[error("enable the compression feature to read compressed paks")]
|
||||||
Compression,
|
Compression,
|
||||||
|
|
||||||
|
#[error("enable the encryption feature to read encrypted paks")]
|
||||||
|
Encryption,
|
||||||
|
|
||||||
#[error("enable the oodle feature to read oodle paks")]
|
#[error("enable the oodle feature to read oodle paks")]
|
||||||
Oodle,
|
Oodle,
|
||||||
|
|
||||||
|
|
116
repak/src/pak.rs
116
repak/src/pak.rs
|
@ -1,5 +1,6 @@
|
||||||
use super::ext::{ReadExt, WriteExt};
|
use super::ext::{ReadExt, WriteExt};
|
||||||
use super::{Version, VersionMajor};
|
use super::{Version, VersionMajor};
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
use aes::Aes256;
|
use aes::Aes256;
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
@ -8,6 +9,7 @@ use std::io::{self, Read, Seek, Write};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PakReader {
|
pub struct PakReader {
|
||||||
pak: Pak,
|
pak: Pak,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +17,7 @@ pub struct PakReader {
|
||||||
pub struct PakWriter<W: Write + Seek> {
|
pub struct PakWriter<W: Write + Seek> {
|
||||||
pak: Pak,
|
pak: Pak,
|
||||||
writer: W,
|
writer: W,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +73,7 @@ impl Index {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Error> {
|
fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Error> {
|
||||||
if let Some(key) = key {
|
if let Some(key) = key {
|
||||||
use aes::cipher::BlockDecrypt;
|
use aes::cipher::BlockDecrypt;
|
||||||
|
@ -83,28 +87,79 @@ fn decrypt(key: Option<&aes::Aes256>, bytes: &mut [u8]) -> Result<(), super::Err
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PakReader {
|
impl PakReader {
|
||||||
pub fn new_any<R: Read + Seek>(
|
#[cfg(not(feature = "encryption"))]
|
||||||
|
pub fn new_any<R: Read + Seek>(reader: &mut R) -> Result<Self, super::Error> {
|
||||||
|
Self::new_any_inner(reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
pub fn new_any_with_key<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
|
) -> Result<Self, super::Error> {
|
||||||
|
Self::new_any_inner(reader, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_any_inner<R: Read + Seek>(
|
||||||
|
reader: &mut R,
|
||||||
|
#[cfg(feature = "encryption")] key: Option<aes::Aes256>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
let mut log = "\n".to_owned();
|
let mut log = "\n".to_owned();
|
||||||
|
|
||||||
for ver in Version::iter() {
|
for ver in Version::iter() {
|
||||||
match Pak::read(&mut *reader, ver, key.as_ref()) {
|
match Pak::read(
|
||||||
Ok(pak) => return Ok(Self { pak, key }),
|
&mut *reader,
|
||||||
|
ver,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
key.as_ref(),
|
||||||
|
) {
|
||||||
|
Ok(pak) => {
|
||||||
|
return Ok(Self {
|
||||||
|
pak,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
key,
|
||||||
|
})
|
||||||
|
}
|
||||||
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
|
Err(err) => writeln!(log, "trying version {} failed: {}", ver, err)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(super::Error::UnsupportedOrEncrypted(log))
|
Err(super::Error::UnsupportedOrEncrypted(log))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
pub fn new<R: Read + Seek>(
|
pub fn new<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
|
) -> Result<Self, super::Error> {
|
||||||
|
Self::new_inner(reader, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
pub fn new_with_key<R: Read + Seek>(
|
||||||
|
reader: &mut R,
|
||||||
|
version: super::Version,
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
Pak::read(reader, version, key.as_ref()).map(|pak| Self { pak, key })
|
Self::new_inner(reader, version, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_inner<R: Read + Seek>(
|
||||||
|
reader: &mut R,
|
||||||
|
version: super::Version,
|
||||||
|
#[cfg(feature = "encryption")] key: Option<aes::Aes256>,
|
||||||
|
) -> Result<Self, super::Error> {
|
||||||
|
Pak::read(
|
||||||
|
reader,
|
||||||
|
version,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
key.as_ref(),
|
||||||
|
)
|
||||||
|
.map(|pak| Self {
|
||||||
|
pak,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
key,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn version(&self) -> super::Version {
|
pub fn version(&self) -> super::Version {
|
||||||
|
@ -140,6 +195,7 @@ impl PakReader {
|
||||||
reader,
|
reader,
|
||||||
self.pak.version,
|
self.pak.version,
|
||||||
&self.pak.compression,
|
&self.pak.compression,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
self.key.as_ref(),
|
self.key.as_ref(),
|
||||||
writer,
|
writer,
|
||||||
),
|
),
|
||||||
|
@ -158,6 +214,7 @@ impl PakReader {
|
||||||
writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?;
|
writer.seek(io::SeekFrom::Start(self.pak.index_offset.unwrap()))?;
|
||||||
Ok(PakWriter {
|
Ok(PakWriter {
|
||||||
pak: self.pak,
|
pak: self.pak,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
key: self.key,
|
key: self.key,
|
||||||
writer,
|
writer,
|
||||||
})
|
})
|
||||||
|
@ -165,7 +222,21 @@ impl PakReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write + Seek> PakWriter<W> {
|
impl<W: Write + Seek> PakWriter<W> {
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
writer: W,
|
||||||
|
version: Version,
|
||||||
|
mount_point: String,
|
||||||
|
path_hash_seed: Option<u64>,
|
||||||
|
) -> Self {
|
||||||
|
PakWriter {
|
||||||
|
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||||
|
writer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
pub fn new_with_key(
|
||||||
writer: W,
|
writer: W,
|
||||||
key: Option<aes::Aes256>,
|
key: Option<aes::Aes256>,
|
||||||
version: Version,
|
version: Version,
|
||||||
|
@ -179,6 +250,21 @@ impl<W: Write + Seek> PakWriter<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_inner(
|
||||||
|
writer: W,
|
||||||
|
#[cfg(feature = "encryption")] key: Option<aes::Aes256>,
|
||||||
|
version: Version,
|
||||||
|
mount_point: String,
|
||||||
|
path_hash_seed: Option<u64>,
|
||||||
|
) -> Self {
|
||||||
|
PakWriter {
|
||||||
|
pak: Pak::new(version, mount_point, path_hash_seed),
|
||||||
|
writer,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn into_writer(self) -> W {
|
pub fn into_writer(self) -> W {
|
||||||
self.writer
|
self.writer
|
||||||
}
|
}
|
||||||
|
@ -219,7 +305,11 @@ impl<W: Write + Seek> PakWriter<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_index(mut self) -> Result<W, super::Error> {
|
pub fn write_index(mut self) -> Result<W, super::Error> {
|
||||||
self.pak.write(&mut self.writer, self.key)?;
|
self.pak.write(
|
||||||
|
&mut self.writer,
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
|
self.key,
|
||||||
|
)?;
|
||||||
Ok(self.writer)
|
Ok(self.writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,17 +318,21 @@ impl Pak {
|
||||||
fn read<R: Read + Seek>(
|
fn read<R: Read + Seek>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
version: super::Version,
|
version: super::Version,
|
||||||
key: Option<&aes::Aes256>,
|
#[cfg(feature = "encryption")] key: Option<&aes::Aes256>,
|
||||||
) -> Result<Self, super::Error> {
|
) -> Result<Self, super::Error> {
|
||||||
// read footer to get index, encryption & compression info
|
// read footer to get index, encryption & compression info
|
||||||
reader.seek(io::SeekFrom::End(-version.size()))?;
|
reader.seek(io::SeekFrom::End(-version.size()))?;
|
||||||
let footer = super::footer::Footer::read(reader, version)?;
|
let footer = super::footer::Footer::read(reader, version)?;
|
||||||
// read index to get all the entry info
|
// read index to get all the entry info
|
||||||
reader.seek(io::SeekFrom::Start(footer.index_offset))?;
|
reader.seek(io::SeekFrom::Start(footer.index_offset))?;
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut index = reader.read_len(footer.index_size as usize)?;
|
let mut index = reader.read_len(footer.index_size as usize)?;
|
||||||
|
|
||||||
// decrypt index if needed
|
// decrypt index if needed
|
||||||
if footer.encrypted {
|
if footer.encrypted {
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
|
return Err(super::Error::Encryption);
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
decrypt(key, &mut index)?;
|
decrypt(key, &mut index)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,6 +354,9 @@ impl Pak {
|
||||||
// TODO verify hash
|
// TODO verify hash
|
||||||
|
|
||||||
if footer.encrypted {
|
if footer.encrypted {
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
|
return Err(super::Error::Encryption);
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
decrypt(key, &mut path_hash_index_buf)?;
|
decrypt(key, &mut path_hash_index_buf)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,11 +380,15 @@ impl Pak {
|
||||||
let _full_directory_index_hash = index.read_len(20)?;
|
let _full_directory_index_hash = index.read_len(20)?;
|
||||||
|
|
||||||
reader.seek(io::SeekFrom::Start(full_directory_index_offset))?;
|
reader.seek(io::SeekFrom::Start(full_directory_index_offset))?;
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut full_directory_index =
|
let mut full_directory_index =
|
||||||
reader.read_len(full_directory_index_size as usize)?;
|
reader.read_len(full_directory_index_size as usize)?;
|
||||||
// TODO verify hash
|
// TODO verify hash
|
||||||
|
|
||||||
if footer.encrypted {
|
if footer.encrypted {
|
||||||
|
#[cfg(not(feature = "encryption"))]
|
||||||
|
return Err(super::Error::Encryption);
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
decrypt(key, &mut full_directory_index)?;
|
decrypt(key, &mut full_directory_index)?;
|
||||||
}
|
}
|
||||||
let mut fdi = io::Cursor::new(full_directory_index);
|
let mut fdi = io::Cursor::new(full_directory_index);
|
||||||
|
@ -367,7 +468,7 @@ impl Pak {
|
||||||
fn write<W: Write + Seek>(
|
fn write<W: Write + Seek>(
|
||||||
&self,
|
&self,
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
_key: Option<aes::Aes256>,
|
#[cfg(feature = "encryption")] _key: Option<aes::Aes256>,
|
||||||
) -> Result<(), super::Error> {
|
) -> Result<(), super::Error> {
|
||||||
let index_offset = writer.stream_position()?;
|
let index_offset = writer.stream_position()?;
|
||||||
|
|
||||||
|
@ -594,6 +695,7 @@ fn pad_zeros_to_alignment(v: &mut Vec<u8>, alignment: usize) {
|
||||||
assert!(v.len() % alignment == 0);
|
assert!(v.len() % alignment == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
fn encrypt(key: Aes256, bytes: &mut [u8]) {
|
fn encrypt(key: Aes256, bytes: &mut [u8]) {
|
||||||
use aes::cipher::BlockEncrypt;
|
use aes::cipher::BlockEncrypt;
|
||||||
for chunk in bytes.chunks_mut(16) {
|
for chunk in bytes.chunks_mut(16) {
|
||||||
|
|
|
@ -175,7 +175,10 @@ fn main() -> Result<(), repak::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn info(aes_key: Option<aes::Aes256>, action: ActionInfo) -> Result<(), repak::Error> {
|
fn info(aes_key: Option<aes::Aes256>, action: ActionInfo) -> Result<(), repak::Error> {
|
||||||
let pak = repak::PakReader::new_any(&mut BufReader::new(File::open(action.input)?), aes_key)?;
|
let pak = repak::PakReader::new_any_with_key(
|
||||||
|
&mut BufReader::new(File::open(action.input)?),
|
||||||
|
aes_key,
|
||||||
|
)?;
|
||||||
println!("mount point: {}", pak.mount_point());
|
println!("mount point: {}", pak.mount_point());
|
||||||
println!("version: {}", pak.version());
|
println!("version: {}", pak.version());
|
||||||
println!("version major: {}", pak.version().version_major());
|
println!("version major: {}", pak.version().version_major());
|
||||||
|
@ -186,7 +189,10 @@ fn info(aes_key: Option<aes::Aes256>, action: ActionInfo) -> Result<(), repak::E
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(aes_key: Option<aes::Aes256>, action: ActionList) -> Result<(), repak::Error> {
|
fn list(aes_key: Option<aes::Aes256>, action: ActionList) -> Result<(), repak::Error> {
|
||||||
let pak = repak::PakReader::new_any(&mut BufReader::new(File::open(action.input)?), aes_key)?;
|
let pak = repak::PakReader::new_any_with_key(
|
||||||
|
&mut BufReader::new(File::open(action.input)?),
|
||||||
|
aes_key,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mount_point = PathBuf::from(pak.mount_point());
|
let mount_point = PathBuf::from(pak.mount_point());
|
||||||
let prefix = Path::new(&action.strip_prefix);
|
let prefix = Path::new(&action.strip_prefix);
|
||||||
|
@ -215,7 +221,10 @@ fn list(aes_key: Option<aes::Aes256>, action: ActionList) -> Result<(), repak::E
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_list(aes_key: Option<aes::Aes256>, action: ActionHashList) -> Result<(), repak::Error> {
|
fn hash_list(aes_key: Option<aes::Aes256>, action: ActionHashList) -> Result<(), repak::Error> {
|
||||||
let pak = repak::PakReader::new_any(&mut BufReader::new(File::open(&action.input)?), aes_key)?;
|
let pak = repak::PakReader::new_any_with_key(
|
||||||
|
&mut BufReader::new(File::open(&action.input)?),
|
||||||
|
aes_key,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mount_point = PathBuf::from(pak.mount_point());
|
let mount_point = PathBuf::from(pak.mount_point());
|
||||||
let prefix = Path::new(&action.strip_prefix);
|
let prefix = Path::new(&action.strip_prefix);
|
||||||
|
@ -270,7 +279,10 @@ fn hash_list(aes_key: Option<aes::Aes256>, action: ActionHashList) -> Result<(),
|
||||||
const STYLE: &str = "[{elapsed_precise}] [{wide_bar}] {pos}/{len} ({eta})";
|
const STYLE: &str = "[{elapsed_precise}] [{wide_bar}] {pos}/{len} ({eta})";
|
||||||
|
|
||||||
fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repak::Error> {
|
fn unpack(aes_key: Option<aes::Aes256>, action: ActionUnpack) -> Result<(), repak::Error> {
|
||||||
let pak = repak::PakReader::new_any(&mut BufReader::new(File::open(&action.input)?), aes_key)?;
|
let pak = repak::PakReader::new_any_with_key(
|
||||||
|
&mut BufReader::new(File::open(&action.input)?),
|
||||||
|
aes_key,
|
||||||
|
)?;
|
||||||
let output = action
|
let output = action
|
||||||
.output
|
.output
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
|
@ -388,7 +400,7 @@ fn pack(args: ActionPack) -> Result<(), repak::Error> {
|
||||||
collect_files(&mut paths, input_path)?;
|
collect_files(&mut paths, input_path)?;
|
||||||
paths.sort();
|
paths.sort();
|
||||||
|
|
||||||
let mut pak = repak::PakWriter::new(
|
let mut pak = repak::PakWriter::new_with_key(
|
||||||
BufWriter::new(File::create(&output)?),
|
BufWriter::new(File::create(&output)?),
|
||||||
None,
|
None,
|
||||||
args.version,
|
args.version,
|
||||||
|
@ -423,7 +435,7 @@ fn pack(args: ActionPack) -> Result<(), repak::Error> {
|
||||||
|
|
||||||
fn get(aes_key: Option<aes::Aes256>, args: ActionGet) -> Result<(), repak::Error> {
|
fn get(aes_key: Option<aes::Aes256>, args: ActionGet) -> Result<(), repak::Error> {
|
||||||
let mut reader = BufReader::new(File::open(&args.input)?);
|
let mut reader = BufReader::new(File::open(&args.input)?);
|
||||||
let pak = repak::PakReader::new_any(&mut reader, aes_key)?;
|
let pak = repak::PakReader::new_any_with_key(&mut reader, aes_key)?;
|
||||||
let mount_point = PathBuf::from(pak.mount_point());
|
let mount_point = PathBuf::from(pak.mount_point());
|
||||||
let prefix = Path::new(&args.strip_prefix);
|
let prefix = Path::new(&args.strip_prefix);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue