diff --git a/extractor/tgz_extractor.go b/extractor/tgz_extractor.go index 6522e31..fa8765b 100644 --- a/extractor/tgz_extractor.go +++ b/extractor/tgz_extractor.go @@ -105,5 +105,9 @@ func extractTarArchiveFile(header *tar.Header, dest string, input io.Reader) err defer fileCopy.Close() _, err = io.Copy(fileCopy, input) - return err + if err != nil { + return err + } + + return setXattrsFromTar(filePath, header) } diff --git a/extractor/xattr_unix.go b/extractor/xattr_unix.go new file mode 100644 index 0000000..68310d5 --- /dev/null +++ b/extractor/xattr_unix.go @@ -0,0 +1,29 @@ +//go:build unix + +package extractor + +import ( + "archive/tar" + "errors" + "strings" + "syscall" + + "golang.org/x/sys/unix" +) + +func setXattrsFromTar(path string, hdr *tar.Header) (err error) { + const paxSchilyXattr = "SCHILY.xattr." + + for key, value := range hdr.PAXRecords { + if !strings.HasPrefix(key, paxSchilyXattr) { + continue + } + + err = unix.Lsetxattr(path, key[len(paxSchilyXattr):], []byte(value), 0) + if err != nil && !errors.Is(err, syscall.ENOTSUP) && !errors.Is(err, syscall.EPERM) { + return err + } + } + + return nil +} diff --git a/extractor/xattr_windows.go b/extractor/xattr_windows.go new file mode 100644 index 0000000..f5bfba9 --- /dev/null +++ b/extractor/xattr_windows.go @@ -0,0 +1,9 @@ +//go:build windows + +package extractor + +import "archive/tar" + +func setXattrsFromTar(_ string, _ *tar.Header) error { + return nil +}