forked from pufferpanel/pufferpanel
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfilesystem_windows.go
130 lines (106 loc) · 2.85 KB
/
filesystem_windows.go
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package pufferpanel
import (
"errors"
"os"
"path/filepath"
"strings"
)
func (sfp *fileServer) OpenFile(path string, flags int, mode os.FileMode) (*os.File, error) {
path = prepPath(path)
if path == "" {
return os.Open(sfp.dir)
}
//if this is not a create request, nuke mode
if flags&os.O_CREATE == 0 {
mode = 0
}
//at this point, we are going to work on openat2
fd, err := os.OpenFile(filepath.Join(sfp.dir, path), flags, mode)
if err != nil {
return nil, err
}
fi, err := fd.Stat()
if err != nil {
return nil, err
}
//for windows, hard deny symlinks
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
return nil, errors.New("access denied")
}
return fd, nil
}
func (sfp *fileServer) MkdirAll(path string, mode os.FileMode) error {
//this is going to be recursive...
path = prepPath(path)
//now for each one, we just need to make each path, and hope this works
//in theory, the mkdir will be safe enough
parts := strings.Split(path, string(filepath.Separator))
//if it was just mkdir root... we don't do anything
if len(parts) <= 1 {
return nil
}
var err error
for i := range parts {
err = sfp.Mkdir(filepath.Join(parts[:i]...), mode)
if err != nil && !errors.Is(err, os.ErrExist) {
return err
}
}
return nil
}
func (sfp *fileServer) Rename(source, target string) error {
source = prepPath(source)
target = prepPath(target)
sourceParent := filepath.Dir(source)
targetParent := filepath.Dir(target)
sourceName := filepath.Base(source)
targetName := filepath.Base(target)
sourceFolder, err := sfp.OpenFile(sourceParent, os.O_RDONLY, 0755)
if err != nil {
return err
}
defer Close(sourceFolder)
targetFolder, err := sfp.OpenFile(targetParent, os.O_RDONLY, 0755)
if err != nil {
return err
}
defer Close(targetFolder)
err = os.Rename(filepath.Join(sfp.dir, sourceParent, sourceName), filepath.Join(sfp.dir, targetParent, targetName))
return err
}
func (sfp *fileServer) Mkdir(path string, mode os.FileMode) error {
path = prepPath(path)
parent := filepath.Dir(path)
folder, err := sfp.OpenFile(parent, os.O_RDONLY, mode)
if err != nil {
return err
}
defer Close(folder)
return os.Mkdir(filepath.Join(sfp.dir, path), mode)
}
func (sfp *fileServer) Remove(path string) error {
path = prepPath(path)
parent := filepath.Dir(path)
folder, err := sfp.OpenFile(parent, os.O_RDONLY, 0755)
if err != nil {
return err
}
defer Close(folder)
return os.Remove(filepath.Join(sfp.dir, path))
}
func (sfp *fileServer) RemoveAll(path string) error {
path = prepPath(path)
parent := filepath.Dir(path)
folder, err := sfp.OpenFile(parent, os.O_RDONLY, 0755)
if err != nil {
return err
}
defer Close(folder)
return os.Remove(filepath.Join(sfp.dir, path))
}
func prepPath(path string) string {
path = strings.Replace(path, "/", "\\", -1)
path = filepath.Clean(path)
path = strings.TrimPrefix(path, "\\")
return path
}