Commit 2312d23b authored by SamwiseFilmore's avatar SamwiseFilmore
Browse files

Use BufReader for PackageFile; Fix Temp path finder

parent ee8a482b
......@@ -160,8 +160,8 @@ impl ErrorKind {
}
}
// Core::Error doesn't implement std::Error, so thiserror won't generate this impl
impl From<pkgar_core::Error> for ErrorKind {
// Core::Error doesn't implement std::Error, so thiserror won't generate this impl
fn from(err: pkgar_core::Error) -> ErrorKind {
ErrorKind::Core(err)
}
......
use std::fs::{File, OpenOptions};
use std::io::{Read, Seek, SeekFrom};
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::{Path, PathBuf};
use sodiumoxide::crypto::sign::PublicKey;
......@@ -11,7 +11,7 @@ use crate::ext::PackageSrcExt;
#[derive(Debug)]
pub struct PackageFile {
path: PathBuf,
src: File,
src: BufReader<File>,
header: Header,
}
......@@ -21,12 +21,18 @@ impl PackageFile {
public_key: &PublicKey
) -> Result<PackageFile, Error> {
let zeroes = [0; HEADER_SIZE];
let file = OpenOptions::new()
.read(true)
.open(&path)
.map_err(|e| Error::from(e).path(&path) )?;
let mut new = PackageFile {
path: path.as_ref().to_path_buf(),
src: OpenOptions::new()
.read(true)
.open(&path)
.map_err(|e| Error::from(e).path(path) )?,
src: BufReader::new(file),
// Need a blank header to construct the PackageFile, since we need to
// use a method of PackageSrc in order to get the actual header...
header: unsafe { *Header::new_unchecked(&zeroes)? },
};
......
......@@ -11,15 +11,41 @@ use pkgar_core::{Mode, PackageSrc};
use crate::{Error, ErrorKind, READ_WRITE_HASH_BUF_SIZE};
use crate::ext::{copy_and_hash, EntryExt, PackageSrcExt};
/// Returns `None` if the target path has no parent (was `/`)
fn file_exists(path: impl AsRef<Path>) -> Result<bool, Error> {
if let Err(err) = fs::metadata(&path) {
if err.kind() == io::ErrorKind::NotFound {
Ok(false)
} else {
Err(Error::from(err).path(path))
}
} else {
Ok(true)
}
}
/// Determine the temporary path for a file, and create its parent directories.
/// Returns `Err` if the target path has no parent (was `/`).
fn temp_path(target_path: impl AsRef<Path>, entry_hash: Hash) -> Result<PathBuf, Error> {
let tmp_name = if let Some(filename) = target_path.as_ref().file_name() {
format!(".pkgar.{}", Path::new(filename).display())
let target_path = target_path.as_ref();
let hash_path = format!(".pkgar.{}", entry_hash.to_hex());
let tmp_name = if let Some(filename) = target_path.file_name() {
let name_path = format!(".pkgar.{}", Path::new(filename).display());
if file_exists(&name_path)? {
eprintln!("warn: temporary path already exists at {}", name_path);
hash_path
} else {
name_path
}
} else {
format!(".pkgar.{}", entry_hash.to_hex())
// It's fine to not check the existence of this file, since if the a
// file with the same hash already exists, we know what its
// contents should be.
hash_path
};
let parent = target_path.as_ref().parent()
let parent = target_path.parent()
.ok_or(ErrorKind::InvalidPathComponent(PathBuf::from("/")))?;
fs::create_dir_all(&parent)
.map_err(|e| Error::from(e).path(parent) )?;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment