Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/archive/archives/utils.go
2326 views
1
package archives
2
3
import (
4
"fmt"
5
"io"
6
fs2 "io/fs"
7
"os"
8
"strings"
9
10
"github.com/alist-org/alist/v3/internal/archive/tool"
11
"github.com/alist-org/alist/v3/internal/errs"
12
"github.com/alist-org/alist/v3/internal/model"
13
"github.com/alist-org/alist/v3/internal/stream"
14
"github.com/alist-org/alist/v3/pkg/utils"
15
"github.com/mholt/archives"
16
)
17
18
func getFs(ss *stream.SeekableStream, args model.ArchiveArgs) (*archives.ArchiveFS, error) {
19
reader, err := stream.NewReadAtSeeker(ss, 0)
20
if err != nil {
21
return nil, err
22
}
23
if r, ok := reader.(*stream.RangeReadReadAtSeeker); ok {
24
r.InitHeadCache()
25
}
26
format, _, err := archives.Identify(ss.Ctx, ss.GetName(), reader)
27
if err != nil {
28
return nil, errs.UnknownArchiveFormat
29
}
30
extractor, ok := format.(archives.Extractor)
31
if !ok {
32
return nil, errs.UnknownArchiveFormat
33
}
34
switch f := format.(type) {
35
case archives.SevenZip:
36
f.Password = args.Password
37
case archives.Rar:
38
f.Password = args.Password
39
}
40
return &archives.ArchiveFS{
41
Stream: io.NewSectionReader(reader, 0, ss.GetSize()),
42
Format: extractor,
43
Context: ss.Ctx,
44
}, nil
45
}
46
47
func toModelObj(file os.FileInfo) *model.Object {
48
return &model.Object{
49
Name: file.Name(),
50
Size: file.Size(),
51
Modified: file.ModTime(),
52
IsFolder: file.IsDir(),
53
}
54
}
55
56
func filterPassword(err error) error {
57
if err != nil && strings.Contains(err.Error(), "password") {
58
return errs.WrongArchivePassword
59
}
60
return err
61
}
62
63
func decompress(fsys fs2.FS, filePath, dstPath string, up model.UpdateProgress) error {
64
rc, err := fsys.Open(filePath)
65
if err != nil {
66
return err
67
}
68
defer rc.Close()
69
stat, err := rc.Stat()
70
if err != nil {
71
return err
72
}
73
if !stat.Mode().IsRegular() {
74
return fmt.Errorf("%w: %s", tool.ErrArchiveIllegalPath, filePath)
75
}
76
f, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
77
if err != nil {
78
return err
79
}
80
defer f.Close()
81
_, err = utils.CopyWithBuffer(f, &stream.ReaderUpdatingProgress{
82
Reader: &stream.SimpleReaderWithSize{
83
Reader: rc,
84
Size: stat.Size(),
85
},
86
UpdateProgress: up,
87
})
88
return err
89
}
90
91