diff options
Diffstat (limited to 'src/launcher/extract.rs')
| -rw-r--r-- | src/launcher/extract.rs | 136 |
1 files changed, 0 insertions, 136 deletions
diff --git a/src/launcher/extract.rs b/src/launcher/extract.rs deleted file mode 100644 index 8c5f2b8..0000000 --- a/src/launcher/extract.rs +++ /dev/null @@ -1,136 +0,0 @@ -use std::error::Error; -use std::fmt::{Display, Formatter}; -use std::{fs, io, os}; -use std::fs::File; -use std::io::{BufReader, Error as IOError, Read}; -use std::path::{Path, PathBuf}; -use log::{debug, trace}; -use zip::result::ZipError; -use zip::ZipArchive; -use crate::util; - -#[derive(Debug)] -pub enum ZipExtractError { - IO { what: &'static str, error: IOError }, - Zip { what: &'static str, error: ZipError }, - InvalidEntry { why: &'static str, name: String } -} - -impl From<(&'static str, IOError)> for ZipExtractError { - fn from((what, error): (&'static str, IOError)) -> Self { - ZipExtractError::IO { what, error } - } -} - -impl From<(&'static str, ZipError)> for ZipExtractError { - fn from((what, error): (&'static str, ZipError)) -> Self { - ZipExtractError::Zip { what, error } - } -} - -impl Display for ZipExtractError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - ZipExtractError::IO { what, error } => write!(f, "i/o error ({what}): {error}"), - ZipExtractError::Zip { what, error } => write!(f, "zip error ({what}): {error}"), - ZipExtractError::InvalidEntry { why, name } => write!(f, "invalid entry in zip file ({why}): {name}") - } - } -} - -impl Error for ZipExtractError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - match self { - ZipExtractError::IO { error, .. } => Some(error), - ZipExtractError::Zip { error, .. } => Some(error), - _ => None - } - } -} - -fn check_entry_path(name: &str) -> Result<&Path, ZipExtractError> { - util::check_path(name).map_err(|e| ZipExtractError::InvalidEntry { - why: e, - name: name.to_owned() - }) -} - -#[cfg(unix)] -fn extract_symlink(path: impl AsRef<Path>, target: &str) -> io::Result<()> { - os::unix::fs::symlink(target, path) -} - -#[cfg(windows)] -fn extract_symlink(path: impl AsRef<Path>, target: &str) -> io::Result<()> { - os::windows::fs::symlink_file(target, path) -} - -#[cfg(not(any(unix, windows)))] -fn extract_symlink(path: impl AsRef<Path>, _target: &str) -> io::Result<()> { - warn!("Refusing to extract symbolic link to {}. I don't know how to do it on this platform!", path.as_ref().display()); - Ok(()) -} - -pub fn extract_zip<F>(zip_path: impl AsRef<Path>, extract_root: impl AsRef<Path>, condition: F) -> Result<usize, ZipExtractError> -where - F: Fn(&str) -> bool -{ - debug!("Extracting zip file {} into {}", zip_path.as_ref().display(), extract_root.as_ref().display()); - - fs::create_dir_all(&extract_root).map_err(|e| ZipExtractError::from(("create extract root", e)))?; - - let mut extracted = 0usize; - - let file = File::open(&zip_path).map_err(|e| ZipExtractError::from(("extract zip file (open)", e)))?; - let read = BufReader::new(file); - - let mut archive = ZipArchive::new(read).map_err(|e| ZipExtractError::from(("read zip archive", e)))?; - - // create directories - for n in 0..archive.len() { - let entry = archive.by_index(n).map_err(|e| ZipExtractError::from(("read zip entry (1)", e)))?; - if !entry.is_dir() { continue; } - - let name = entry.name(); - if !condition(name) { - continue; - } - - let entry_path = check_entry_path(name)?; - let entry_path: PathBuf = [extract_root.as_ref(), entry_path].iter().collect(); - - trace!("Extracting directory {} from {}", entry.name(), zip_path.as_ref().display()); - fs::create_dir_all(entry_path).map_err(|e| ZipExtractError::from(("extract directory", e)))?; - } - - // extract the files - for n in 0..archive.len() { - let mut entry = archive.by_index(n).map_err(|e| ZipExtractError::from(("read zip entry (2)", e)))?; - let name = entry.name(); - - if entry.is_dir() { continue; } - - if !condition(name) { - continue; - } - - let entry_path = check_entry_path(name)?; - let entry_path: PathBuf = [extract_root.as_ref(), entry_path].iter().collect(); - - if entry.is_symlink() { - let mut target = String::new(); - entry.read_to_string(&mut target).map_err(|e| ZipExtractError::from(("read to symlink target", e)))?; - - trace!("Extracting symbolic link {} -> {} from {}", entry.name(), target, zip_path.as_ref().display()); - extract_symlink(entry_path.as_path(), target.as_str()).map_err(|e| ZipExtractError::from(("extract symlink", e)))?; - } else if entry.is_file() { - let mut outfile = File::create(&entry_path).map_err(|e| ZipExtractError::from(("extract zip entry (open)", e)))?; - - trace!("Extracting file {} from {}", entry.name(), zip_path.as_ref().display()); - io::copy(&mut entry, &mut outfile).map_err(|e| ZipExtractError::from(("extract zip entry (write)", e)))?; - extracted += 1; - } - } - - Ok(extracted) -} |
