all repos — homestead @ f0db45107699eb1294f6d64cbf2ddd48783f7cc0

Code for my website

domain/content/fetcher/tar.go (view raw)

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
}