use ic_host_artifacts::artifact::{ArtifactError, ArtifactIdentity, hash_reader, read_reader};
use std::{fs::File, path::Path};
#[cfg(unix)]
mod no_follow;
#[cfg(unix)]
pub use no_follow::read_file_no_follow;
#[cfg(unix)]
pub use no_follow::read_optional_file_no_follow;
#[cfg(unix)]
mod private;
#[cfg(unix)]
pub use private::{PrivateFileReadError, read_private_bytes};
#[cfg(test)]
mod tests;
pub fn hash_file(path: &Path, max_bytes: u64) -> Result<ArtifactIdentity, ArtifactError> {
hash_reader(open_file(path, max_bytes)?, max_bytes)
}
pub fn read_file(path: &Path, max_bytes: usize) -> Result<Vec<u8>, ArtifactError> {
read_reader(open_file(path, max_bytes as u64)?, max_bytes)
}
pub fn read_opened_file(file: File, max_bytes: usize) -> Result<Vec<u8>, ArtifactError> {
check_metadata(&file.metadata()?, max_bytes as u64)?;
read_reader(file, max_bytes)
}
fn open_file(path: &Path, limit: u64) -> Result<File, ArtifactError> {
check_metadata(&std::fs::metadata(path)?, limit)?;
let file = File::open(path)?;
check_metadata(&file.metadata()?, limit)?;
Ok(file)
}
fn check_metadata(metadata: &std::fs::Metadata, limit: u64) -> Result<(), ArtifactError> {
if !metadata.is_file() {
return Err(ArtifactError::NotRegularFile);
}
if metadata.len() > limit {
return Err(ArtifactError::LimitExceeded { limit });
}
Ok(())
}