From b8d53f43b6050096f3d6edb83111db11bbe44d47 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 3 Aug 2023 14:31:12 +0200 Subject: [PATCH] fix(server): actually serve desc & files in db archives --- libarchive/src/archive.rs | 6 ++++++ libarchive/src/write/file.rs | 34 ++++++++++++++++++++++------------ server/src/repo/manager.rs | 8 ++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/libarchive/src/archive.rs b/libarchive/src/archive.rs index faaacc9..d8f7086 100644 --- a/libarchive/src/archive.rs +++ b/libarchive/src/archive.rs @@ -314,6 +314,12 @@ pub trait Entry { ffi::archive_entry_set_mode(self.entry_mut(), mode); } } + + fn set_size(&mut self, size: i64) { + unsafe { + ffi::archive_entry_set_size(self.entry_mut(), size); + } + } } #[derive(Debug, PartialEq, Eq)] diff --git a/libarchive/src/write/file.rs b/libarchive/src/write/file.rs index 08f2b45..9c7abe2 100644 --- a/libarchive/src/write/file.rs +++ b/libarchive/src/write/file.rs @@ -39,22 +39,32 @@ impl FileWriter { } } - let mut buf = [0; 8192]; + let mut buf = [0; 4096]; loop { match r.read(&mut buf) { Ok(0) => return Ok(()), - Ok(written) => unsafe { - match ffi::archive_write_data( - self.handle_mut(), - buf.as_ptr() as *const _, - written, - ) as i32 - { - ffi::ARCHIVE_OK => (), - _ => return Err(ArchiveError::from(self as &dyn Handle).into()), - }; - }, + // Write entire buffer + Ok(buf_len) => { + let mut written: usize = 0; + + while written < buf_len { + let res = unsafe { + ffi::archive_write_data( + self.handle_mut(), + &buf[written] as *const u8 as *const _, + buf_len - written, + ) + } as isize; + + // Negative values signal errors + if res < 0 { + return Err(ArchiveError::from(self as &dyn Handle).into()); + } + + written += usize::try_from(res).unwrap(); + } + } Err(err) => match err.kind() { io::ErrorKind::Interrupted => (), _ => return Err(err.into()), diff --git a/server/src/repo/manager.rs b/server/src/repo/manager.rs index f5aad8c..411cf98 100644 --- a/server/src/repo/manager.rs +++ b/server/src/repo/manager.rs @@ -65,9 +65,13 @@ impl RepoGroupManager { // The desc file needs to be added to both archives let path_in_tar = PathBuf::from(entry.file_name()).join("desc"); let src_path = entry.path().join("desc"); + let metadata = src_path.metadata()?; let mut ar_entry = WriteEntry::new(); ar_entry.set_pathname(&path_in_tar); + // These small text files will definitely fit inside an i64 + ar_entry.set_size(metadata.len().try_into().unwrap()); + ar_entry.set_filetype(libarchive::archive::FileType::RegularFile); ar_entry.set_mode(0o100644); ar_db.append_path(&mut ar_entry, &src_path)?; @@ -76,10 +80,14 @@ impl RepoGroupManager { // The files file is only required in the files database let path_in_tar = PathBuf::from(entry.file_name()).join("files"); let src_path = entry.path().join("files"); + let metadata = src_path.metadata()?; let mut ar_entry = WriteEntry::new(); + ar_entry.set_filetype(libarchive::archive::FileType::RegularFile); ar_entry.set_pathname(&path_in_tar); ar_entry.set_mode(0o100644); + // These small text files will definitely fit inside an i64 + ar_entry.set_size(metadata.len().try_into().unwrap()); ar_files.append_path(&mut ar_entry, src_path)?; }