Compares the hash digest of a file with the recorded data in an [`Mtree`]. Takes an `mtree` against which a `file_name` in `input_dir` is checked. Returns the absolute path to the file and a byte buffer that represents the contents of the file. # Errors Returns an error if - the file path (`input_dir` + `file_name`) does not exist, - the file can not be read, - the hash digest of the file does
(
mtree: &Mtree,
input_dir: &InputDir,
file_name: &str,
)
| 185 | /// - the hash digest of the file does not match that initially recorded in `mtree`, |
| 186 | /// - or the file can not be found in `mtree`. |
| 187 | fn compare_digests( |
| 188 | mtree: &Mtree, |
| 189 | input_dir: &InputDir, |
| 190 | file_name: &str, |
| 191 | ) -> Result<(PathBuf, Vec<u8>), crate::Error> { |
| 192 | let path = input_dir.join(file_name); |
| 193 | |
| 194 | if !path.exists() { |
| 195 | return Err(Error::FileIsMissing { |
| 196 | path: PathBuf::from(file_name), |
| 197 | input_dir: input_dir.to_path_buf(), |
| 198 | } |
| 199 | .into()); |
| 200 | } |
| 201 | |
| 202 | // Read the file to a buffer. |
| 203 | let buf = read(path.as_path()).map_err(|source| crate::Error::IoPath { |
| 204 | path: path.clone(), |
| 205 | context: t!("error-io-read-file"), |
| 206 | source, |
| 207 | })?; |
| 208 | |
| 209 | // Create a custom file name for searching in ALPM-MTREE entries, as they are prefixed with |
| 210 | // MTREE_PATH_PREFIX. |
| 211 | let mtree_file_name = PathBuf::from(MTREE_PATH_PREFIX).join(file_name); |
| 212 | |
| 213 | // Create a SHA-256 hash digest for the file. |
| 214 | let current_digest = Sha256Checksum::calculate_from(&buf); |
| 215 | |
| 216 | // Check if the initial hash digest of the file - recorded in ALPM-MTREE data - matches. |
| 217 | if let Some(initial_digest) = match mtree { |
| 218 | Mtree::V1(paths) => paths.as_slice(), |
| 219 | Mtree::V2(paths) => paths.as_slice(), |
| 220 | } |
| 221 | .iter() |
| 222 | .find_map(|path| match path { |
| 223 | alpm_mtree::mtree::v2::Path::File(file) if file.path == mtree_file_name => { |
| 224 | Some(file.sha256_digest.clone()) |
| 225 | } |
| 226 | _ => None, |
| 227 | }) { |
| 228 | if initial_digest != current_digest { |
| 229 | return Err(Error::FileHashDigestChanged { |
| 230 | path: PathBuf::from(file_name), |
| 231 | current_digest, |
| 232 | initial_digest, |
| 233 | input_dir: input_dir.to_path_buf(), |
| 234 | } |
| 235 | .into()); |
| 236 | } |
| 237 | } else { |
| 238 | return Err(Error::FileIsMissing { |
| 239 | path: PathBuf::from(file_name), |
| 240 | input_dir: input_dir.to_path_buf(), |
| 241 | } |
| 242 | .into()); |
| 243 | }; |
| 244 |
no test coverage detected