diff --git a/CHANGELOG.md b/CHANGELOG.md index 789f6847..2bc4f598 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 passphrase when the PGP secret key is passphrase-protected. - Add method `is_no_replace` to `FileOptionsBuilder`, used to set the `%config(noreplace)` flag on a file. +- Added the `FileEntry.linkto` field that is a target of a symbolic link. ## 0.12.1 diff --git a/src/rpm/headers/header.rs b/src/rpm/headers/header.rs index 69d5b87f..d15e80a3 100644 --- a/src/rpm/headers/header.rs +++ b/src/rpm/headers/header.rs @@ -432,6 +432,8 @@ pub struct FileEntry { pub digest: Option, /// Defines any capabilities on the file. pub caps: Option, + /// Defines a target of a symlink (if the file is a symbolic link). + pub linkto: String, } fn parse_entry_data_number<'a, T, E, F>( diff --git a/src/rpm/package.rs b/src/rpm/package.rs index 516c3853..0058dec0 100644 --- a/src/rpm/package.rs +++ b/src/rpm/package.rs @@ -843,8 +843,13 @@ impl PackageMetadata { Err(Error::TagNotFound(_)) => Ok(None), Err(e) => return Err(e), }; + let links = self + .header + .get_entry_data_as_string_array(IndexTag::RPMTAG_FILELINKTOS); - match (modes, users, groups, digests, mtimes, sizes, flags, caps) { + match ( + modes, users, groups, digests, mtimes, sizes, flags, caps, links, + ) { ( Ok(modes), Ok(users), @@ -854,6 +859,7 @@ impl PackageMetadata { Ok(sizes), Ok(flags), Ok(caps), + Ok(links), ) => { let paths = self.get_file_paths()?; let n = paths.len(); @@ -867,11 +873,12 @@ impl PackageMetadata { mtimes, sizes, flags, + links, )) .enumerate() .try_fold::, _, Result<_, Error>>( Vec::with_capacity(n), - |mut acc, (idx, (path, user, group, mode, digest, mtime, size, flags))| { + |mut acc, (idx, (path, user, group, mode, digest, mtime, size, flags, linkto))| { let digest = if digest.is_empty() { None } else { @@ -893,6 +900,7 @@ impl PackageMetadata { flags: FileFlags::from_bits_retain(flags), size: size as usize, caps: cap, + linkto: linkto.to_string(), }); Ok(acc) }, @@ -908,8 +916,9 @@ impl PackageMetadata { Err(Error::TagNotFound(_)), Err(Error::TagNotFound(_)), Err(Error::TagNotFound(_)), + Err(Error::TagNotFound(_)), ) => Ok(vec![]), - (modes, users, groups, digests, mtimes, sizes, flags, caps) => { + (modes, users, groups, digests, mtimes, sizes, flags, caps, links) => { modes?; users?; groups?; @@ -918,6 +927,7 @@ impl PackageMetadata { sizes?; flags?; caps?; + links?; unreachable!() } } diff --git a/src/tests.rs b/src/tests.rs index fc4ccee2..fbf99d9b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -5,6 +5,10 @@ fn rpm_389_ds_file_path() -> std::path::PathBuf { cargo_manifest_dir().join("test_assets/389-ds-base-devel-1.3.8.4-15.el7.x86_64.rpm") } +fn rpm_freesrp_file_path() -> std::path::PathBuf { + cargo_manifest_dir().join("test_assets/freesrp-udev-0.3.0-1.25.x86_64.rpm") +} + fn cargo_manifest_dir() -> std::path::PathBuf { std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) } @@ -333,6 +337,20 @@ fn test_rpm_header() -> Result<(), Box> { // Verify that if there are no capabilities set then the caps field is None package.metadata.get_file_entries()?.iter().for_each(|f| { + match f.mode { + FileMode::SymbolicLink { permissions: _ } => { + assert_ne!("", f.linkto); + match f.path.to_str().unwrap() { + "/usr/lib64/dirsrv/libldaputil.so" => { + assert_eq!("libldaputil.so.0.0.0", f.linkto) + } + "/usr/lib64/dirsrv/libslapd.so" => assert_eq!("libslapd.so.0.1.0", f.linkto), + _ => {} + } + } + _ => assert_eq!("", f.linkto), + } + assert_eq!(f.clone().caps, None); }); @@ -340,3 +358,13 @@ fn test_rpm_header() -> Result<(), Box> { Ok(()) } + +#[test] +fn test_rpm_no_symlinks() -> Result<(), Box> { + let rpm_file_path = rpm_freesrp_file_path(); + let package = Package::open(rpm_file_path)?; + + assert_eq!(1, package.metadata.get_file_entries()?.len()); + + Ok(()) +} diff --git a/test_assets/freesrp-udev-0.3.0-1.25.x86_64.rpm b/test_assets/freesrp-udev-0.3.0-1.25.x86_64.rpm new file mode 100644 index 00000000..8ebe2ee8 Binary files /dev/null and b/test_assets/freesrp-udev-0.3.0-1.25.x86_64.rpm differ