package fetcher
import (
"archive/tar"
"compress/bzip2"
"io"
"os"
"alin.ovh/x/log"
"github.com/Southclaws/fault"
"github.com/Southclaws/fault/fmsg"
)
func bunzip(r io.Reader) io.Reader {
return bzip2.NewReader(r)
}
func extract(body io.Reader, root *os.Root, log *log.Logger) error {
tr := tar.NewReader(body)
for {
head, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return fault.Wrap(err, fmsg.With("could not read tar header"))
}
log.Debug("extracting file", "name", head.Name)
switch head.Typeflag {
case tar.TypeReg:
err := writeFile(tr, head, root)
if err != nil {
return fault.Wrap(err, fmsg.Withf("could not write file %s", head.Name))
}
case tar.TypeDir:
err := root.MkdirAll(head.Name, head.FileInfo().Mode().Perm())
if err != nil {
return fault.Wrap(err, fmsg.Withf("could not create directory %s", head.Name))
}
default:
return fault.Newf("unsupported file type %d", head.Typeflag)
}
}
return nil
}
func writeFile(tr *tar.Reader, head *tar.Header, root *os.Root) error {
file, err := root.OpenFile(head.Name, os.O_CREATE|os.O_WRONLY, head.FileInfo().Mode().Perm())
if err != nil {
return fault.Wrap(err, fmsg.Withf("could not open file %s", head.Name))
}
defer file.Close()
_, err = io.Copy(file, tr)
if err != nil {
return fault.Wrap(err, fmsg.Withf("could not write file %s", head.Name))
}
err = file.Sync()
if err != nil {
return fault.Wrap(err, fmsg.Withf("could not sync file %s", head.Name))
}
return nil
}
domain/content/fetcher/tar.go (view raw)