Add create_archive
function
This commit is contained in:
parent
e5cbf16064
commit
8a3bd19185
@ -3,6 +3,14 @@ use {
|
|||||||
std::io::{Read, Write},
|
std::io::{Read, Write},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum Algorithm {
|
||||||
|
Md5,
|
||||||
|
Sha1,
|
||||||
|
Sha256,
|
||||||
|
Skip,
|
||||||
|
}
|
||||||
|
|
||||||
/// Optional checksumming for individual files
|
/// Optional checksumming for individual files
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Checksum {
|
pub enum Checksum {
|
||||||
@ -20,7 +28,7 @@ pub enum Checksum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Checksum {
|
impl Checksum {
|
||||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
match buf[0] {
|
match buf[0] {
|
||||||
@ -43,7 +51,7 @@ impl Checksum {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Md5(sum) => {
|
Self::Md5(sum) => {
|
||||||
writer.write_all(&[b'0'])?;
|
writer.write_all(&[b'0'])?;
|
||||||
|
@ -18,7 +18,7 @@ pub struct File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||||
let mut len = [0; 8];
|
let mut len = [0; 8];
|
||||||
reader.read_exact(&mut len)?;
|
reader.read_exact(&mut len)?;
|
||||||
let len = u64::from_le_bytes(len);
|
let len = u64::from_le_bytes(len);
|
||||||
@ -77,7 +77,7 @@ impl File {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||||
writer.write_all(&self.len.to_be_bytes())?;
|
writer.write_all(&self.len.to_be_bytes())?;
|
||||||
Checksum::write(&self.checksum, writer)?;
|
Checksum::write(&self.checksum, writer)?;
|
||||||
writer.write_all(&self.data)?;
|
writer.write_all(&self.data)?;
|
||||||
|
@ -25,7 +25,7 @@ pub enum FileType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FileType {
|
impl FileType {
|
||||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
match buf[0] {
|
match buf[0] {
|
||||||
@ -67,7 +67,7 @@ impl FileType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Normal(f) => {
|
Self::Normal(f) => {
|
||||||
writer.write_all(&[0])?;
|
writer.write_all(&[0])?;
|
||||||
|
21
src/lib.rs
21
src/lib.rs
@ -1,13 +1,30 @@
|
|||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
use std::{fs, collections::HashMap, io::BufWriter, sync::Mutex};
|
||||||
|
|
||||||
mod checksum;
|
mod checksum;
|
||||||
mod error;
|
mod error;
|
||||||
mod file;
|
mod file;
|
||||||
mod filetype;
|
mod filetype;
|
||||||
pub mod nix;
|
pub(crate) mod nix;
|
||||||
mod node;
|
mod node;
|
||||||
mod special;
|
mod special;
|
||||||
mod stream;
|
mod stream;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
checksum::Checksum, error::Error, file::File, filetype::FileType, node::Node, special::Special,
|
checksum::{Algorithm, Checksum}, error::Error, file::File, filetype::FileType, node::Node, special::Special,
|
||||||
stream::Stream,
|
stream::Stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn create_archive(path: &str, files: Vec<&str>, algorithm: Algorithm) -> Result<(), Error> {
|
||||||
|
let fd = fs::OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(path)?;
|
||||||
|
let mut writer = BufWriter::new(fd);
|
||||||
|
let mut links = Mutex::new(HashMap::new());
|
||||||
|
for f in files.iter() {
|
||||||
|
let node = Node::from_path(f, algorithm, &mut links)?;
|
||||||
|
node.write(&mut writer)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#![allow(clippy::must_use_candidate)]
|
#![allow(clippy::must_use_candidate)]
|
||||||
|
//! Low level Unix api functions
|
||||||
use {
|
use {
|
||||||
crate::Error,
|
crate::Error,
|
||||||
std::{ffi::CString, io},
|
std::{ffi::CString, io},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Get the effective user id of the current process
|
||||||
pub fn geteuid() -> u32 {
|
pub fn geteuid() -> u32 {
|
||||||
unsafe { libc::geteuid() }
|
unsafe { libc::geteuid() }
|
||||||
}
|
}
|
||||||
|
21
src/node.rs
21
src/node.rs
@ -1,5 +1,5 @@
|
|||||||
use {
|
use {
|
||||||
crate::{nix, Checksum, Error, File, FileType, Special},
|
crate::{nix, Algorithm, Checksum, Error, File, FileType, Special},
|
||||||
md5::{Digest, Md5},
|
md5::{Digest, Md5},
|
||||||
sha1::Sha1,
|
sha1::Sha1,
|
||||||
sha2::Sha256,
|
sha2::Sha256,
|
||||||
@ -121,7 +121,7 @@ impl Node {
|
|||||||
/// avoid writing their data out more than once.
|
/// avoid writing their data out more than once.
|
||||||
pub fn from_path(
|
pub fn from_path(
|
||||||
path: &str,
|
path: &str,
|
||||||
checksum: Checksum,
|
algorithm: Algorithm,
|
||||||
links: &Mutex<HashMap<u64, String>>,
|
links: &Mutex<HashMap<u64, String>>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let name = String::from(path);
|
let name = String::from(path);
|
||||||
@ -167,26 +167,26 @@ impl Node {
|
|||||||
let mut len = meta.len();
|
let mut len = meta.len();
|
||||||
let mut data = Vec::with_capacity(len.try_into()?);
|
let mut data = Vec::with_capacity(len.try_into()?);
|
||||||
len = reader.read_to_end(&mut data)?.try_into()?;
|
len = reader.read_to_end(&mut data)?.try_into()?;
|
||||||
let checksum = match checksum {
|
let checksum = match algorithm {
|
||||||
Checksum::Md5(mut cs) => {
|
Algorithm::Md5 => {
|
||||||
let mut hasher = Md5::new();
|
let mut hasher = Md5::new();
|
||||||
hasher.update(&data);
|
hasher.update(&data);
|
||||||
cs = hasher.finalize().into();
|
let cs = hasher.finalize().into();
|
||||||
Checksum::Md5(cs)
|
Checksum::Md5(cs)
|
||||||
}
|
}
|
||||||
Checksum::Sha1(mut cs) => {
|
Algorithm::Sha1 => {
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
hasher.update(&data);
|
hasher.update(&data);
|
||||||
cs = hasher.finalize().into();
|
let cs = hasher.finalize().into();
|
||||||
Checksum::Sha1(cs)
|
Checksum::Sha1(cs)
|
||||||
}
|
}
|
||||||
Checksum::Sha256(mut cs) => {
|
Algorithm::Sha256 => {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(&data);
|
hasher.update(&data);
|
||||||
cs = hasher.finalize().into();
|
let cs = hasher.finalize().into();
|
||||||
Checksum::Sha256(cs)
|
Checksum::Sha256(cs)
|
||||||
}
|
}
|
||||||
Checksum::Skip => checksum,
|
Algorithm::Skip => Checksum::Skip,
|
||||||
};
|
};
|
||||||
break 'blk FileType::Normal(File {
|
break 'blk FileType::Normal(File {
|
||||||
len,
|
len,
|
||||||
@ -208,6 +208,7 @@ impl Node {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recreates the original file on disk which this node represents
|
||||||
pub fn extract(&self, prefix: Option<&str>) -> Result<(), Error> {
|
pub fn extract(&self, prefix: Option<&str>) -> Result<(), Error> {
|
||||||
let euid = nix::geteuid();
|
let euid = nix::geteuid();
|
||||||
let path = 'blk: {
|
let path = 'blk: {
|
||||||
|
@ -11,7 +11,7 @@ pub struct Special {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Special {
|
impl Special {
|
||||||
pub fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
let major: [u8; 4] = buf[..4].try_into()?;
|
let major: [u8; 4] = buf[..4].try_into()?;
|
||||||
@ -21,7 +21,7 @@ impl Special {
|
|||||||
Ok(Self { major, minor })
|
Ok(Self { major, minor })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
|
||||||
writer.write_all(&self.major.to_le_bytes())?;
|
writer.write_all(&self.major.to_le_bytes())?;
|
||||||
writer.write_all(&self.minor.to_le_bytes())?;
|
writer.write_all(&self.minor.to_le_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user