From dfb5be349af98db984a0944f49896f454e4bc8a6 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Thu, 10 Apr 2025 15:08:06 +0200 Subject: pkg/osutil: add tar.gz generation helpers --- pkg/osutil/tar.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 pkg/osutil/tar.go (limited to 'pkg/osutil/tar.go') diff --git a/pkg/osutil/tar.go b/pkg/osutil/tar.go new file mode 100644 index 000000000..32500e7e4 --- /dev/null +++ b/pkg/osutil/tar.go @@ -0,0 +1,67 @@ +// Copyright 2025 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package osutil + +import ( + "archive/tar" + "compress/gzip" + "io" + "io/fs" + "os" + "path/filepath" + "strings" +) + +func TarGzDirectory(dir string, writer io.Writer) error { + gzw := gzip.NewWriter(writer) + defer gzw.Close() + return tarDirectory(dir, gzw) +} + +func tarDirectory(dir string, writer io.Writer) error { + tw := tar.NewWriter(writer) + defer tw.Close() + + return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if err != nil || path == dir { + return err + } + typ := d.Type() + if !typ.IsDir() && !typ.IsRegular() { + // Only folders and regular files. + return nil + } + relPath, err := filepath.Rel(dir, path) + if err != nil { + return err + } + relPath = filepath.ToSlash(relPath) + info, err := d.Info() + if err != nil { + return err + } + header, err := tar.FileInfoHeader(info, "") + if err != nil { + return err + } + header.Name = relPath + if typ.IsDir() && !strings.HasSuffix(header.Name, "/") { + header.Name += "/" + } + if err := tw.WriteHeader(header); err != nil { + return err + } + if typ.IsDir() { + return nil + } + // Write the file content. + f, err := os.Open(path) + if err != nil { + return err + } + _, err = io.Copy(tw, f) + f.Close() + return err + }) +} -- cgit mrf-deployment