Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,365 changes: 0 additions & 1,365 deletions implants/lib/eldritchv2/stdlib/eldritch-libfile/src/std.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use ::std::fs::OpenOptions;
use ::std::io::Write;
use alloc::format;
use alloc::string::String;

pub fn append(path: String, content: String) -> Result<(), String> {
let mut file = OpenOptions::new()
.create(true)
.append(true)
.open(&path)
.map_err(|e| format!("Failed to open file {path}: {e}"))?;

file.write_all(content.as_bytes())
.map_err(|e| format!("Failed to write to file {path}: {e}"))?;

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use tempfile::NamedTempFile;

#[test]
fn test_append() {
let tmp = NamedTempFile::new().unwrap();
let path = tmp.path().to_string_lossy().to_string();

// Write initial
::std::fs::write(&path, "hello").unwrap();

append(path.clone(), " world".to_string()).unwrap();

let content = ::std::fs::read_to_string(&path).unwrap();
assert_eq!(content, "hello world");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#[cfg(feature = "stdlib")]
use alloc::string::String;
#[cfg(feature = "stdlib")]
use alloc::string::ToString;
#[cfg(feature = "stdlib")]
use anyhow::{Context, Result as AnyhowResult};
#[cfg(feature = "stdlib")]
use std::fs::File;
#[cfg(feature = "stdlib")]
use std::path::Path;

#[cfg(feature = "stdlib")]
pub fn compress(src: String, dst: String) -> Result<(), String> {
compress_impl(src, dst).map_err(|e| e.to_string())
}

#[cfg(not(feature = "stdlib"))]
pub fn compress(
_src: alloc::string::String,
_dst: alloc::string::String,
) -> Result<(), alloc::string::String> {
Err("compress requires stdlib feature".into())
}

#[cfg(feature = "stdlib")]
fn compress_impl(src: String, dst: String) -> AnyhowResult<()> {
use flate2::Compression;
use std::fs::OpenOptions;
use tempfile::NamedTempFile;

let src_path = Path::new(&src);

// Determine if we need to tar
let tmp_tar_file_src = NamedTempFile::new()?;
let tmp_src = if src_path.is_dir() {
let tmp_path = tmp_tar_file_src.path().to_str().unwrap().to_string();
tar_dir(&src, &tmp_path)?;
tmp_path
} else {
src.clone()
};

let f_src = ::std::io::BufReader::new(File::open(&tmp_src)?);
let f_dst = ::std::io::BufWriter::new(
OpenOptions::new()
.create(true)
.write(true)
.truncate(false)
.open(&dst)?,
);

let mut deflater = flate2::write::GzEncoder::new(f_dst, Compression::fast());
let mut reader = f_src;
::std::io::copy(&mut reader, &mut deflater)?;
deflater.finish()?;

Ok(())
}

#[cfg(feature = "stdlib")]
fn tar_dir(src: &str, dst: &str) -> AnyhowResult<()> {
use tar::{Builder, HeaderMode};

let src_path = Path::new(src);
let file = File::create(dst)?;
let mut tar_builder = Builder::new(file);
tar_builder.mode(HeaderMode::Deterministic);

let src_name = src_path.file_name().context("Failed to get file name")?;

tar_builder.append_dir_all(src_name, src_path)?;
tar_builder.finish()?;
Ok(())
}

#[cfg(test)]
#[cfg(feature = "stdlib")]
mod tests {
use super::*;
use std::fs;
use tempfile::NamedTempFile;

#[test]
fn test_compress() {
let content = "Compression Test";
let tmp_src = NamedTempFile::new().unwrap();
let src_path = tmp_src.path().to_string_lossy().to_string();
fs::write(&src_path, content).unwrap();

let tmp_dst = NamedTempFile::new().unwrap();
let dst_path = tmp_dst.path().to_string_lossy().to_string();

compress(src_path.clone(), dst_path.clone()).unwrap();

let meta = fs::metadata(&dst_path).unwrap();
assert!(meta.len() > 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use ::std::fs;
use alloc::format;
use alloc::string::String;

pub fn copy(src: String, dst: String) -> Result<(), String> {
fs::copy(&src, &dst).map_err(|e| format!("Failed to copy {src} to {dst}: {e}"))?;
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;

#[test]
fn test_copy() {
let tmp_dir = tempfile::tempdir().unwrap();
let src = tmp_dir.path().join("src.txt");
let dst = tmp_dir.path().join("dst.txt");

fs::write(&src, "copy me").unwrap();

copy(
src.to_string_lossy().to_string(),
dst.to_string_lossy().to_string(),
)
.unwrap();

assert!(src.exists());
assert!(dst.exists());
assert_eq!(fs::read_to_string(dst).unwrap(), "copy me");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#[cfg(feature = "stdlib")]
use alloc::string::String;
#[cfg(feature = "stdlib")]
use alloc::string::ToString;
#[cfg(feature = "stdlib")]
use alloc::vec::Vec;
#[cfg(feature = "stdlib")]
use anyhow::Result as AnyhowResult;
#[cfg(feature = "stdlib")]
use std::fs::{self, File};
#[cfg(feature = "stdlib")]
use std::io::Read;
#[cfg(feature = "stdlib")]
use std::path::Path;

#[cfg(feature = "stdlib")]
pub fn decompress(src: String, dst: String) -> Result<(), String> {
decompress_impl(src, dst).map_err(|e| e.to_string())
}

#[cfg(not(feature = "stdlib"))]
pub fn decompress(
_src: alloc::string::String,
_dst: alloc::string::String,
) -> Result<(), alloc::string::String> {
Err("decompress requires stdlib feature".into())
}

#[cfg(feature = "stdlib")]
fn decompress_impl(src: String, dst: String) -> AnyhowResult<()> {
use tar::Archive;

let f_src = ::std::io::BufReader::new(File::open(&src)?);
let mut decoder = flate2::read::GzDecoder::new(f_src);

let mut decoded_data = Vec::new();
decoder.read_to_end(&mut decoded_data)?;

// Try as tar
// Create a temp dir to verify if it is a tar
if Archive::new(decoded_data.as_slice()).entries().is_ok() {
// It's likely a tar

let dst_path = Path::new(&dst);
if !dst_path.exists() {
fs::create_dir_all(dst_path)?;
}

let mut archive = Archive::new(decoded_data.as_slice());

let tmp_dir = tempfile::tempdir()?;
match archive.unpack(tmp_dir.path()) {
Ok(_) => {
if dst_path.exists() {
fs::remove_dir_all(dst_path).ok(); // ignore fail
}

// Keep the temp dir content by moving it
let path = tmp_dir.keep();
fs::rename(&path, &dst)?;
Ok(())
}
Err(_) => {
// Not a tar or unpack failed. Write raw bytes.
if dst_path.exists() && dst_path.is_dir() {
fs::remove_dir_all(dst_path)?;
}
fs::write(&dst, decoded_data)?;
Ok(())
}
}
} else {
// Not a tar
fs::write(&dst, decoded_data)?;
Ok(())
}
}

#[cfg(test)]
#[cfg(feature = "stdlib")]
mod tests {
use super::*;
use flate2::Compression;
use flate2::write::GzEncoder;
use std::io::Write;
use tempfile::NamedTempFile;

#[test]
fn test_decompress() {
let content = "Decompression Test";
let tmp_src = NamedTempFile::new().unwrap();
let src_path = tmp_src.path().to_string_lossy().to_string();

// Create a gzip file manually
let file = File::create(&src_path).unwrap();
let mut encoder = GzEncoder::new(file, Compression::default());
encoder.write_all(content.as_bytes()).unwrap();
encoder.finish().unwrap();

let tmp_dst = NamedTempFile::new().unwrap();
let dst_path = tmp_dst.path().to_string_lossy().to_string();

decompress(src_path, dst_path.clone()).unwrap();

let res = fs::read_to_string(&dst_path).unwrap();
assert_eq!(res, content);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use ::std::path::Path;
use alloc::string::String;

pub fn exists(path: String) -> Result<bool, String> {
Ok(Path::new(&path).exists())
}

#[cfg(test)]
mod tests {
use super::*;
use tempfile::NamedTempFile;

#[test]
fn test_exists() {
let tmp = NamedTempFile::new().unwrap();
let path = tmp.path().to_string_lossy().to_string();

assert!(exists(path).unwrap());
assert!(!exists("nonexistent_file_12345".to_string()).unwrap());
}
}
Loading
Loading