2020-03-27 20:08:06 +00:00
|
|
|
package tarutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/tar"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2022-06-14 15:00:51 +00:00
|
|
|
"golang.org/x/xerrors"
|
2020-03-27 20:08:06 +00:00
|
|
|
)
|
|
|
|
|
2020-04-01 23:18:20 +00:00
|
|
|
var log = logging.Logger("tarutil") // nolint
|
2020-03-27 20:08:06 +00:00
|
|
|
|
2021-11-24 19:08:37 +00:00
|
|
|
func ExtractTar(body io.Reader, dir string, buf []byte) error {
|
2020-08-16 10:40:35 +00:00
|
|
|
if err := os.MkdirAll(dir, 0755); err != nil { // nolint
|
2020-03-27 20:08:06 +00:00
|
|
|
return xerrors.Errorf("mkdir: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tr := tar.NewReader(body)
|
|
|
|
for {
|
|
|
|
header, err := tr.Next()
|
|
|
|
switch err {
|
|
|
|
default:
|
|
|
|
return err
|
|
|
|
case io.EOF:
|
|
|
|
return nil
|
|
|
|
|
|
|
|
case nil:
|
|
|
|
}
|
|
|
|
|
2022-04-20 09:34:01 +00:00
|
|
|
//nolint:gosec
|
2020-03-27 20:08:06 +00:00
|
|
|
f, err := os.Create(filepath.Join(dir, header.Name))
|
|
|
|
if err != nil {
|
2022-04-20 09:34:01 +00:00
|
|
|
//nolint:gosec
|
2020-03-27 20:08:06 +00:00
|
|
|
return xerrors.Errorf("creating file %s: %w", filepath.Join(dir, header.Name), err)
|
|
|
|
}
|
|
|
|
|
2020-08-20 04:49:10 +00:00
|
|
|
// This data is coming from a trusted source, no need to check the size.
|
|
|
|
//nolint:gosec
|
2021-11-24 19:08:37 +00:00
|
|
|
if _, err := io.CopyBuffer(f, tr, buf); err != nil {
|
2020-03-27 20:08:06 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := f.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-24 19:08:37 +00:00
|
|
|
func TarDirectory(dir string, w io.Writer, buf []byte) error {
|
2020-03-27 20:08:06 +00:00
|
|
|
tw := tar.NewWriter(w)
|
|
|
|
|
2022-09-09 11:53:40 +00:00
|
|
|
files, err := os.ReadDir(dir)
|
2020-03-27 20:08:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, file := range files {
|
2022-09-09 11:53:40 +00:00
|
|
|
info, err := file.Info()
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("getting file info for file %s: %w", file.Name(), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
h, err := tar.FileInfoHeader(info, "")
|
2020-03-27 20:08:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("getting header for file %s: %w", file.Name(), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := tw.WriteHeader(h); err != nil {
|
|
|
|
return xerrors.Errorf("wiritng header for file %s: %w", file.Name(), err)
|
|
|
|
}
|
|
|
|
|
2020-04-01 23:18:20 +00:00
|
|
|
f, err := os.OpenFile(filepath.Join(dir, file.Name()), os.O_RDONLY, 644) // nolint
|
2020-03-27 20:08:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("opening %s for reading: %w", file.Name(), err)
|
|
|
|
}
|
|
|
|
|
2021-11-24 19:08:37 +00:00
|
|
|
if _, err := io.CopyBuffer(tw, f, buf); err != nil {
|
2020-03-27 20:08:06 +00:00
|
|
|
return xerrors.Errorf("copy data for file %s: %w", file.Name(), err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := f.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|