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 }