Skip to main content

inspect_regular_file/
inspect_regular_file.rs

1//! Inspect a local regular file, rejecting its final symlink without mutation.
2
3#[cfg(unix)]
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    use ic_host_tools::artifact::{Sha256Digest, read_file_no_follow};
6    use std::{io, path::Path};
7
8    let mut args = std::env::args_os().skip(1);
9    let path = args.next().ok_or_else(|| {
10        io::Error::new(
11            io::ErrorKind::InvalidInput,
12            "usage: inspect_regular_file PATH MAX_BYTES",
13        )
14    })?;
15    let max_bytes = args
16        .next()
17        .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "missing byte limit"))?
18        .into_string()
19        .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "byte limit must be UTF-8"))?
20        .parse()?;
21    if args.next().is_some() {
22        return Err(io::Error::new(io::ErrorKind::InvalidInput, "unexpected argument").into());
23    }
24    let bytes = read_file_no_follow(Path::new(&path), max_bytes)?;
25    println!(
26        "raw_bytes={} sha256={}",
27        bytes.len(),
28        Sha256Digest::compute(&bytes)
29    );
30    Ok(())
31}
32
33#[cfg(not(unix))]
34fn main() -> Result<(), Box<dyn std::error::Error>> {
35    Err(std::io::Error::new(
36        std::io::ErrorKind::Unsupported,
37        "final-symlink rejection requires a Unix host",
38    )
39    .into())
40}