From 8a26eac6a2ff689debea8ddc655583118a802dcc Mon Sep 17 00:00:00 2001 From: tommady Date: Wed, 9 Apr 2025 01:47:47 +0000 Subject: [PATCH] let tar on archive not follow symlink but only archive the symlink itself Signed-off-by: tommady --- src/archive/tar.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/archive/tar.rs b/src/archive/tar.rs index 3416078..d5a61fe 100644 --- a/src/archive/tar.rs +++ b/src/archive/tar.rs @@ -8,7 +8,7 @@ use std::{ thread, }; -use fs_err as fs; +use fs_err::{self as fs}; use same_file::Handle; use crate::{ @@ -127,6 +127,30 @@ where if path.is_dir() { builder.append_dir(path, path)?; + } else if path.is_symlink() { + let target_path = path.read_link()?; + + let mut header = tar::Header::new_gnu(); + header.set_entry_type(tar::EntryType::Symlink); + header.set_size(0); + + let entry_name = path.to_str().ok_or_else(|| { + FinalError::with_title("Tar requires that all directories names are valid UTF-8") + .detail(format!("File at '{path:?}' has a non-UTF-8 name")) + })?; + + let target_name = target_path.to_str().ok_or_else(|| { + FinalError::with_title("Tar requires that all directories names are valid UTF-8") + .detail(format!("File at '{target_path:?}' has a non-UTF-8 name")) + })?; + + builder + .append_link(&mut header, entry_name, target_name) + .map_err(|err| { + FinalError::with_title("Could not create archive") + .detail("Unexpected error while trying to read link") + .detail(format!("Error: {err}.")) + })?; } else { let mut file = match fs::File::open(path) { Ok(f) => f,