File size: 1,299 Bytes
7def60a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
69
70
package utils

import (
	"fmt"
	"os"

	"github.com/mholt/archiver/v3"
)

func IsArchive(file string) bool {
	uaIface, err := archiver.ByExtension(file)
	if err != nil {
		return false
	}

	_, ok := uaIface.(archiver.Unarchiver)
	return ok
}

func ExtractArchive(archive, dst string) error {
	uaIface, err := archiver.ByExtension(archive)
	if err != nil {
		return err
	}

	un, ok := uaIface.(archiver.Unarchiver)
	if !ok {
		return fmt.Errorf("format specified by source filename is not an archive format: %s (%T)", archive, uaIface)
	}

	mytar := &archiver.Tar{
		OverwriteExisting:      true,
		MkdirAll:               true,
		ImplicitTopLevelFolder: false,
		ContinueOnError:        true,
	}

	switch v := uaIface.(type) {
	case *archiver.Tar:
		uaIface = mytar
	case *archiver.TarBrotli:
		v.Tar = mytar
	case *archiver.TarBz2:
		v.Tar = mytar
	case *archiver.TarGz:
		v.Tar = mytar
	case *archiver.TarLz4:
		v.Tar = mytar
	case *archiver.TarSz:
		v.Tar = mytar
	case *archiver.TarXz:
		v.Tar = mytar
	case *archiver.TarZstd:
		v.Tar = mytar
	}

	err = archiver.Walk(archive, func(f archiver.File) error {
		if f.FileInfo.Mode()&os.ModeSymlink != 0 {
			return fmt.Errorf("archive contains a symlink")
		}
		return nil
	})

	if err != nil {
		return err
	}

	return un.Unarchive(archive, dst)
}