feat(libarchive): added FileWritter, also apparently formatted sys
parent
f9c5faeda8
commit
eb9f6a5cb1
|
@ -56,7 +56,7 @@ pub enum ReadFilter {
|
||||||
Rpm,
|
Rpm,
|
||||||
Uu,
|
Uu,
|
||||||
Xz,
|
Xz,
|
||||||
Zstd
|
Zstd,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadFilter {
|
impl ReadFilter {
|
||||||
|
@ -69,7 +69,7 @@ impl ReadFilter {
|
||||||
ReadFilter::Lzma => Some(".lzma"),
|
ReadFilter::Lzma => Some(".lzma"),
|
||||||
ReadFilter::Xz => Some(".xz"),
|
ReadFilter::Xz => Some(".xz"),
|
||||||
ReadFilter::Zstd => Some(".zstd"),
|
ReadFilter::Zstd => Some(".zstd"),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod archive;
|
pub mod archive;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
|
mod write;
|
||||||
|
|
||||||
pub use archive::{
|
pub use archive::{
|
||||||
Entry, ExtractOption, ExtractOptions, Handle, ReadCompression, ReadFilter, ReadFormat,
|
Entry, ExtractOption, ExtractOptions, Handle, ReadCompression, ReadFilter, ReadFormat,
|
||||||
|
|
|
@ -2,7 +2,6 @@ use crate::archive::Entry;
|
||||||
use crate::error::ArchiveError;
|
use crate::error::ArchiveError;
|
||||||
use crate::read::Archive;
|
use crate::read::Archive;
|
||||||
use libarchive3_sys::ffi;
|
use libarchive3_sys::ffi;
|
||||||
use libc::{c_void, ssize_t};
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::marker;
|
use std::marker;
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub trait Archive: Handle + Sized {
|
||||||
3 => Some(ReadFilter::Compress),
|
3 => Some(ReadFilter::Compress),
|
||||||
5 => Some(ReadFilter::Lzma),
|
5 => Some(ReadFilter::Lzma),
|
||||||
6 => Some(ReadFilter::Xz),
|
6 => Some(ReadFilter::Xz),
|
||||||
14 =>Some( ReadFilter::Zstd),
|
14 => Some(ReadFilter::Zstd),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
@ -1,10 +1,10 @@
|
||||||
mod repo;
|
mod repo;
|
||||||
|
|
||||||
|
use axum::extract::FromRef;
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use repo::RepoGroupManager;
|
use repo::RepoGroupManager;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{RwLock, Arc};
|
use std::sync::{Arc, RwLock};
|
||||||
use axum::extract::FromRef;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
|
Loading…
Reference in New Issue