Fix long filenames when creating tar header from metadata and filename

rather than path
This commit is contained in:
Nathan Fisher 2023-03-28 19:16:38 -04:00
parent 4c80e08731
commit 3d0151610d
1 changed files with 18 additions and 0 deletions

View File

@ -281,6 +281,21 @@ impl Header {
owner: Option<Owner>,
) -> Result<Self, Error> {
let mut header = Header::default();
let (filename, prefix) = if filename.len() < 100 {
(filename.to_string(), None)
} else {
// Deal with file names longer than 100 bytes
let path = PathBuf::from(&filename);
let name = match path.file_name().and_then(|n| n.to_str()) {
Some(n) => n.to_string(),
None => return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Cannot get file name"))),
};
let dir = match path.parent() {
Some(d) => d,
None => return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Cannot get path prefix"))),
};
(name, Some(format!("{}", dir.display())))
};
header.fname[..filename.len()].copy_from_slice(filename.as_bytes());
let mode = format!("{:07o}", meta.st_mode());
header.mode[..mode.len()].copy_from_slice(mode.as_bytes());
@ -301,6 +316,9 @@ impl Header {
header.size[..size.len()].copy_from_slice(size.as_bytes());
let mtime = format!("{:011o}", meta.st_mtime());
header.mtime[..mtime.len()].copy_from_slice(mtime.as_bytes());
if let Some(prefix) = prefix {
header.file_prefix[..prefix.len()].copy_from_slice(prefix.as_bytes());
}
header.link_indicator[0] = FileType::from(meta) as u8;
if header.link_indicator[0] == FileType::Symlink as u8 {
let link = fs::read_link(filename)?.to_str().unwrap().to_string();