domain/content/fetcher/tar.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 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
}
|