From af41d1c00624f1fa7db93f16c719f12059044ef0 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Fri, 5 May 2023 19:07:44 -0400 Subject: [PATCH] Fix bug introduced revolving around the ustar `prefix` field. GNU tar was not giving the full path to each file and ignoring the `prefix` field. On investigation, the field is only to be used if the filename is longer than 100 bytes. Since the library code had been simplified to always use the prefix field this caused all filenames shorter than 100 bytes to fail. Also updated `package-bootstrap` to the latest patch release, which has a fix for completions being installed into the base directory rather than the appropriate subdirectory. --- Cargo.lock | 146 +++++++++++++++++------------------------ specs.ron | 16 +++++ src/hpk.rs | 17 +++-- src/installer/hooks.rs | 9 ++- src/package/mod.rs | 4 ++ src/tar/header.rs | 74 ++++++++++++--------- test/2.tar | Bin 10240 -> 10240 bytes 7 files changed, 141 insertions(+), 125 deletions(-) create mode 100644 specs.ron diff --git a/Cargo.lock b/Cargo.lock index fe7821b..0900733 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,42 +19,51 @@ dependencies = [ [[package]] name = "anstream" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", + "colorchoice", "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ "utf8parse", ] [[package]] -name = "anstyle-wincon" -version = "0.2.0" +name = "anstyle-query" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -110,9 +119,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "byteorder" @@ -153,18 +162,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.1" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.2.1" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" dependencies = [ "anstream", "anstyle", @@ -175,9 +184,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.2.0" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" +checksum = "1a19591b2ab0e3c04b588a0e04ddde7b9eaa423646d1b4a8092879216bf47473" dependencies = [ "clap", ] @@ -219,19 +228,10 @@ dependencies = [ ] [[package]] -name = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" - -[[package]] -name = "concolor-query" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" -dependencies = [ - "windows-sys 0.45.0", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "console" @@ -264,9 +264,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -357,7 +357,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.14", + "syn 2.0.15", ] [[package]] @@ -374,7 +374,7 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.14", + "syn 2.0.15", ] [[package]] @@ -480,9 +480,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", @@ -680,9 +680,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "link-cplusplus" @@ -695,9 +695,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "log" @@ -725,9 +725,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -781,9 +781,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "package-bootstrap" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b733f09d474cde789d5a1f62eae77e27749f65a88306a9f60d37d7f5193f2beb" +checksum = "b44f1db147048186ea8be34e803e16ad50a5eb47c9ab6a8e098276a6c8d112dd" dependencies = [ "clap", "clap_complete", @@ -799,9 +799,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" @@ -899,9 +899,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", @@ -1009,22 +1009,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.160" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.14", + "syn 2.0.15", ] [[package]] @@ -1074,9 +1074,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.14" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -1115,7 +1115,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.14", + "syn 2.0.15", ] [[package]] @@ -1417,7 +1417,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets", ] [[package]] @@ -1435,37 +1435,13 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -1569,9 +1545,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.1" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" dependencies = [ "memchr", ] diff --git a/specs.ron b/specs.ron new file mode 100644 index 0000000..deafeb9 --- /dev/null +++ b/specs.ron @@ -0,0 +1,16 @@ +Specs( + name: "hpk", + version: SemVer(SemVer( + major: 0, + minor: 1, + patch: 0, + )), + release: 1, + description: "The HitchHiker Package Keeper", + long_description: "", + dependencies: [], + users: None, + groups: None, + shells: None, + post_install: None, +) diff --git a/src/hpk.rs b/src/hpk.rs index 2ea4c57..2d2c598 100644 --- a/src/hpk.rs +++ b/src/hpk.rs @@ -99,6 +99,7 @@ fn create(matches: &ArgMatches) -> Result<(), Box> { Message::Success(_s) => { pb.inc(1); pb.finish_and_clear(); + break; } } } @@ -114,6 +115,18 @@ fn create(matches: &ArgMatches) -> Result<(), Box> { } } +fn install(matches: &ArgMatches) -> Result<(), Box> { + let Some(root) = matches.get_one::("root") else { + unreachable!(); + }; + if let Some(archive) = matches.get_one::("local") { + install_local(archive, root)?; + } else if let Some(package) = matches.get_one::("package") { + unimplemented!(); + } + Ok(()) +} + fn install_local + fmt::Display>( archive: P, root: P, @@ -168,10 +181,6 @@ fn search(_matches: &ArgMatches) -> Result<(), Box> { unimplemented!(); } -fn install(_matches: &ArgMatches) -> Result<(), Box> { - unimplemented!(); -} - fn remove(_matches: &ArgMatches) -> Result<(), Box> { unimplemented!(); } diff --git a/src/installer/hooks.rs b/src/installer/hooks.rs index 5c09576..3b9b12f 100644 --- a/src/installer/hooks.rs +++ b/src/installer/hooks.rs @@ -1,9 +1,11 @@ use crate::{Group, InstallError, InstallMessage, User}; use std::{ + fs::OpenOptions, + io::{Read, Seek, SeekFrom, Write}, path::PathBuf, process::{Command, Output}, sync::mpsc::Sender, - thread, fs::OpenOptions, io::{Seek, Read, Write, SeekFrom}, + thread, }; #[derive(Debug, Clone)] @@ -154,10 +156,7 @@ pub fn append_shells( let mut f = PathBuf::from(root); f.push("etc"); f.push("shells"); - let mut fd = OpenOptions::new() - .read(true) - .write(true) - .open(&f)?; + let mut fd = OpenOptions::new().read(true).write(true).open(&f)?; let meta = fd.metadata()?; let len = meta.len(); let pos = fd.seek(SeekFrom::Start(len - 1))?; diff --git a/src/package/mod.rs b/src/package/mod.rs index 5d4a5a9..a73e1ed 100644 --- a/src/package/mod.rs +++ b/src/package/mod.rs @@ -129,4 +129,8 @@ impl Package { && (self.version > other.version || (self.version == other.version && self.release > other.release)) } + + pub fn resolve_deps(&self, queue: &mut Vec) -> Result<(), Box> { + unimplemented!(); + } } diff --git a/src/tar/header.rs b/src/tar/header.rs index 0f5dc84..c1ac102 100644 --- a/src/tar/header.rs +++ b/src/tar/header.rs @@ -125,7 +125,7 @@ impl Header { /// /// let header = Header::new("test/1.txt").unwrap(); /// let filename = header.filename().unwrap(); - /// assert_eq!(filename.as_str(), "1.txt"); + /// assert_eq!(filename.as_str(), "test/1.txt"); /// ``` pub fn filename(&self) -> Result { let mut s = String::new(); @@ -220,14 +220,18 @@ impl Header { } /// Gets the path to the file minus it's final component + /// > Note: the ustar format only uses this field if the + /// > complete filename would be longer than 100 bytes. + /// > If the combined filename is shorter, this function + /// > returns `None`. /// /// # Example /// ``` /// use hpk::tar::Header; /// /// let header = Header::new("test/1.txt").unwrap(); - /// let prefix = header.prefix().unwrap(); - /// assert_eq!(prefix.as_str(), "test"); + /// let prefix = header.prefix(); + /// assert!(prefix.is_none()); /// ``` pub fn prefix(&self) -> Option { let mut s = String::new(); @@ -272,20 +276,24 @@ impl Header { let meta = fs::symlink_metadata(filename)?; let (filename, prefix) = { // Original tar has a maximum file name length of 100 bytes. The ustar - // revision allows storing the path prefix separately, with 100 bytes - // reserved for the file name and 150 bytes for the rest of the path. - let path = PathBuf::from(&filename); - let name = match path.file_name().and_then(OsStr::to_str) { - Some(n) => n.to_string(), - None => { - return Err(Error::Io(io::Error::new( - io::ErrorKind::Other, - "Cannot get file name", - ))) - } - }; - let dir = path.parent().map(|x| format!("{}", x.display())); - (name, dir) + // revision allows storing the path prefix separately if the combined + // length is more than 100 bytes. + if filename.len() > 100 { + let path = PathBuf::from(&filename); + let name = match path.file_name().and_then(OsStr::to_str) { + Some(n) => n.to_string(), + None => { + return Err(Error::Io(io::Error::new( + io::ErrorKind::Other, + "Cannot get file name", + ))) + } + }; + let dir = path.parent().map(|x| format!("{}", x.display())); + (name, dir) + } else { + (filename.to_string(), None) + } }; /* Fill in metadata */ @@ -338,20 +346,24 @@ impl Header { let mut header = Header::default(); let (filename, prefix) = { // Original tar has a maximum file name length of 100 bytes. The ustar - // revision allows storing the path prefix separately, with 100 bytes - // reserved for the file name and 150 bytes for the rest of the path. - let path = PathBuf::from(&filename); - let name = match path.file_name().and_then(OsStr::to_str) { - Some(n) => n.to_string(), - None => { - return Err(Error::Io(io::Error::new( - io::ErrorKind::Other, - "Cannot get file name", - ))) - } - }; - let dir = path.parent().map(|x| format!("{}", x.display())); - (name, dir) + // revision allows storing the path prefix separately if the combined + // length is more than 100 bytes. + if filename.len() > 100 { + let path = PathBuf::from(&filename); + let name = match path.file_name().and_then(OsStr::to_str) { + Some(n) => n.to_string(), + None => { + return Err(Error::Io(io::Error::new( + io::ErrorKind::Other, + "Cannot get file name", + ))) + } + }; + let dir = path.parent().map(|x| format!("{}", x.display())); + (name, dir) + } else { + (filename.to_string(), None) + } }; header.fname[..filename.len()].copy_from_slice(filename.as_bytes()); let mode = format!("{:07o}", meta.st_mode()); diff --git a/test/2.tar b/test/2.tar index 7b754362d98bbee0c3361820a486b411811990c2..5441bedc6656679a2d51ddd68847ad246a7a058d 100644 GIT binary patch delta 58 zcmZn&Xb4~}Ni8nXpAbJWMN`1c%+$cxkio#v(7@D$LBU{hB4Y|)X>mznk%9t4USdf` NV%}s$rjLu5)ByEK5hDNq delta 65 zcmZn&Xb506)GMhdnYb{1Vv44Kfq|j9p$UV5p@E5sF@u7^WI@Ihp3>ry#3BU+hP=d* T)QN&VEG4PMB|wSAi