feat(libarchive): added FileWritter, also apparently formatted sys

main
Jef Roosens 2023-07-13 16:39:52 +02:00
parent f9c5faeda8
commit eb9f6a5cb1
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
9 changed files with 837 additions and 573 deletions

View File

@ -56,7 +56,7 @@ pub enum ReadFilter {
Rpm,
Uu,
Xz,
Zstd
Zstd,
}
impl ReadFilter {
@ -69,7 +69,7 @@ impl ReadFilter {
ReadFilter::Lzma => Some(".lzma"),
ReadFilter::Xz => Some(".xz"),
ReadFilter::Zstd => Some(".zstd"),
_ => None
_ => None,
}
}
}

View File

@ -1,6 +1,7 @@
pub mod archive;
pub mod error;
pub mod read;
mod write;
pub use archive::{
Entry, ExtractOption, ExtractOptions, Handle, ReadCompression, ReadFilter, ReadFormat,

View File

@ -2,7 +2,6 @@ use crate::archive::Entry;
use crate::error::ArchiveError;
use crate::read::Archive;
use libarchive3_sys::ffi;
use libc::{c_void, ssize_t};
use std::io;
use std::io::Read;
use std::marker;

View File

@ -0,0 +1,129 @@
use super::file::FileWriter;
use crate::error::ArchiveError;
use crate::Handle;
use crate::{WriteFilter, WriteFormat};
use libarchive3_sys::ffi;
use std::ffi::CString;
use std::path::Path;
pub struct Builder {
handle: *mut ffi::Struct_archive,
consumed: bool,
}
impl Builder {
pub fn new() -> Self {
Builder::default()
}
pub fn add_filter(&mut self, filter: WriteFilter) -> crate::Result<()> {
let result = match filter {
WriteFilter::B64Encode => unsafe {
ffi::archive_write_add_filter_b64encode(self.handle)
},
WriteFilter::Bzip2 => unsafe { ffi::archive_write_add_filter_bzip2(self.handle) },
WriteFilter::Compress => unsafe { ffi::archive_write_add_filter_compress(self.handle) },
WriteFilter::Grzip => unsafe { ffi::archive_write_add_filter_grzip(self.handle) },
WriteFilter::Gzip => unsafe { ffi::archive_write_add_filter_gzip(self.handle) },
WriteFilter::Lrzip => unsafe { ffi::archive_write_add_filter_lrzip(self.handle) },
WriteFilter::Lzip => unsafe { ffi::archive_write_add_filter_lzip(self.handle) },
WriteFilter::Lzma => unsafe { ffi::archive_write_add_filter_lzma(self.handle) },
WriteFilter::Lzop => unsafe { ffi::archive_write_add_filter_lzop(self.handle) },
WriteFilter::None => unsafe { ffi::archive_write_add_filter_none(self.handle) },
WriteFilter::Program(prog) => {
let c_prog = CString::new(prog).unwrap();
unsafe { ffi::archive_write_add_filter_program(self.handle, c_prog.as_ptr()) }
}
WriteFilter::UuEncode => unsafe { ffi::archive_write_add_filter_uuencode(self.handle) },
WriteFilter::Xz => unsafe { ffi::archive_write_add_filter_xz(self.handle) },
};
match result {
ffi::ARCHIVE_OK => Ok(()),
_ => Result::from(self as &dyn Handle),
}
}
pub fn set_format(&self, format: WriteFormat) -> crate::Result<()> {
let result = match format {
WriteFormat::SevenZip => unsafe { ffi::archive_write_set_format_7zip(self.handle) },
WriteFormat::ArBsd => unsafe { ffi::archive_write_set_format_ar_bsd(self.handle) },
WriteFormat::ArSvr4 => unsafe { ffi::archive_write_set_format_ar_svr4(self.handle) },
WriteFormat::Cpio => unsafe { ffi::archive_write_set_format_cpio(self.handle) },
WriteFormat::CpioNewc => unsafe {
ffi::archive_write_set_format_cpio_newc(self.handle)
},
WriteFormat::Gnutar => unsafe { ffi::archive_write_set_format_gnutar(self.handle) },
WriteFormat::Iso9660 => unsafe { ffi::archive_write_set_format_iso9660(self.handle) },
WriteFormat::Mtree => unsafe { ffi::archive_write_set_format_mtree(self.handle) },
WriteFormat::MtreeClassic => unsafe {
ffi::archive_write_set_format_mtree_classic(self.handle)
},
WriteFormat::Pax => unsafe { ffi::archive_write_set_format_pax(self.handle) },
WriteFormat::PaxRestricted => unsafe {
ffi::archive_write_set_format_pax_restricted(self.handle)
},
WriteFormat::Shar => unsafe { ffi::archive_write_set_format_shar(self.handle) },
WriteFormat::SharDump => unsafe {
ffi::archive_write_set_format_shar_dump(self.handle)
},
WriteFormat::Ustar => unsafe { ffi::archive_write_set_format_ustar(self.handle) },
WriteFormat::V7tar => unsafe { ffi::archive_write_set_format_v7tar(self.handle) },
WriteFormat::Xar => unsafe { ffi::archive_write_set_format_xar(self.handle) },
WriteFormat::Zip => unsafe { ffi::archive_write_set_format_zip(self.handle) },
};
match result {
ffi::ARCHIVE_OK => Ok(()),
_ => Result::from(self as &dyn Handle),
}
}
pub fn open_file<T: AsRef<Path>>(mut self, file: T) -> crate::Result<FileWriter> {
if self.consumed {
return Err(ArchiveError::Consumed);
}
let c_file = CString::new(file.as_ref().to_string_lossy().as_bytes()).unwrap();
let res = unsafe { ffi::archive_write_open_filename(self.handle, c_file.as_ptr()) };
match res {
ffi::ARCHIVE_OK => {
self.consumed = true;
Ok(FileWriter::new(self.handle))
}
_ => Err(ArchiveError::from(&self as &dyn Handle)),
}
}
}
impl Default for Builder {
fn default() -> Self {
unsafe {
let handle = ffi::archive_write_new();
if handle.is_null() {
panic!("Allocation error");
}
Builder {
handle,
consumed: false,
}
}
}
}
impl Handle for Builder {
unsafe fn handle(&self) -> *const ffi::Struct_archive {
self.handle as *const _
}
unsafe fn handle_mut(&mut self) -> *mut ffi::Struct_archive {
self.handle
}
}
impl Drop for Builder {
fn drop(&mut self) {
if !self.consumed {
unsafe {
ffi::archive_write_free(self.handle);
}
}
}
}

View File

@ -0,0 +1,79 @@
use super::WriteEntry;
use crate::Entry;
use crate::Handle;
use libarchive3_sys::ffi;
use libarchive3_sys::ffi::c_void;
use std::fs;
use std::io;
use std::io::Read;
use std::path::Path;
pub struct FileWriter {
handle: *mut ffi::Struct_archive,
closed: bool,
}
impl Handle for FileWriter {
unsafe fn handle(&self) -> *const ffi::Struct_archive {
self.handle as *const _
}
unsafe fn handle_mut(&mut self) -> *mut ffi::Struct_archive {
self.handle
}
}
impl FileWriter {
pub fn new(handle: *mut ffi::Struct_archive) -> Self {
FileWriter {
handle,
closed: false,
}
}
pub fn append_path<P: AsRef<Path>>(
&mut self,
entry: &mut WriteEntry,
path: P,
) -> io::Result<()> {
unsafe {
ffi::archive_write_header(self.handle_mut(), entry.entry_mut());
}
let mut f = fs::File::open(path)?;
let mut buf = [0; 8192];
loop {
match f.read(&mut buf) {
Ok(0) => return Ok(()),
Ok(written) => unsafe {
ffi::archive_write_data(self.handle_mut(), buf.as_ptr() as *const _, written);
},
Err(err) => match err.kind() {
io::ErrorKind::Interrupted => (),
_ => return Err(err),
},
};
}
}
pub fn close(&mut self) {
unsafe {
ffi::archive_write_close(self.handle_mut());
}
self.closed = true;
}
}
impl Drop for FileWriter {
fn drop(&mut self) {
if !self.closed {
self.close();
}
unsafe {
ffi::archive_write_free(self.handle_mut());
}
}
}

View File

@ -0,0 +1,34 @@
mod builder;
mod file;
use crate::Entry;
pub use builder::Builder;
use libarchive3_sys::ffi;
pub struct WriteEntry {
entry: *mut ffi::Struct_archive_entry,
}
impl WriteEntry {
pub fn new() -> Self {
let entry = unsafe { ffi::archive_entry_new() };
Self { entry }
}
}
impl Entry for WriteEntry {
unsafe fn entry(&self) -> *const ffi::Struct_archive_entry {
self.entry as *const _
}
unsafe fn entry_mut(&mut self) -> *mut ffi::Struct_archive_entry {
self.entry
}
}
impl Drop for WriteEntry {
fn drop(&mut self) {
unsafe { ffi::archive_entry_free(self.entry_mut()) }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
mod repo;
use axum::extract::FromRef;
use axum::Router;
use repo::RepoGroupManager;
use std::path::PathBuf;
use std::sync::{RwLock, Arc};
use axum::extract::FromRef;
use std::sync::{Arc, RwLock};
#[derive(Clone)]
pub struct Config {