use crate::diagnostic::EnkryptitOutput;
use crate::encryption::encryption_flow::{decrypt_stream, encrypt_stream};
use crate::errors::EnkryptitError;
use crate::types::CompressionType;
use std::fs::File;
use std::io::{BufReader, BufWriter, Seek, SeekFrom};
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
pub fn encrypt_single_file_into_archive(
folder_path: &str,
relative_path: &str,
file_nonce: [u8; 24],
compression: CompressionType,
cipher_key: &[u8; 32],
archive_path: &str,
) -> Result<u64, EnkryptitError> {
let full_file_path = Path::new(folder_path).join(relative_path);
if !PathBuf::from(&full_file_path).exists() {
tracing::warn!("Failed to encrypt an entry : path not found");
EnkryptitOutput::warning("Failed to found an entry. Skipping.").display();
return Ok(0);
}
let file = File::open(full_file_path)?;
let reader = BufReader::new(file);
{
let mut archive = BufWriter::new(File::options().append(true).open(archive_path)?);
encrypt_stream(
&mut archive,
reader,
file_nonce,
cipher_key,
compression,
None,
)
}
}
#[allow(clippy::too_many_arguments)]
pub fn decrypt_single_file_from_archive(
archive_path: &str,
folder_path: &str,
permissions: Option<u32>,
relative_path: &str,
file_nonce: [u8; 24],
compression: CompressionType,
cipher_key: &[u8; 32],
offset: u64,
) -> Result<u64, EnkryptitError> {
let archive = File::open(Path::new(archive_path))?;
let mut reader = BufReader::new(archive);
reader.seek(SeekFrom::Start(offset))?;
let full_file_path = Path::new(folder_path).join(relative_path);
if let Some(parent) = full_file_path.parent() {
std::fs::create_dir_all(parent)?;
}
let file = File::create(full_file_path)?;
if let Some(p) = permissions {
file.set_permissions(std::fs::Permissions::from_mode(p))?;
}
{
let mut writer = BufWriter::new(file);
decrypt_stream(
&mut writer,
reader,
cipher_key,
compression,
file_nonce,
None,
)
}
}