/
file.go
124 lines (104 loc) · 2.02 KB
/
file.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
// +build !windows
package file
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/user"
"strconv"
"syscall"
"time"
)
func cp(srcFile, dstFile string, uid, gid int, m ...os.FileMode) error {
b, err := ioutil.ReadFile(srcFile)
if err != nil {
log.Println(err)
return err
}
dst, err := os.Create(dstFile)
if err != nil {
log.Println(err)
return err
}
defer dst.Close()
if _, err := dst.Write(b); err != nil {
log.Println(err)
return err
}
// rootユーザは 0
// UID/GIDにマイナス値は使わない
if 0 <= uid && 0 <= gid {
if err := dst.Chown(uid, gid); err != nil {
log.Println(err)
// chownはできなくてもしかたないのでreturnしない
}
}
if 1 <= len(m) {
if err := dst.Chmod(m[0]); err != nil {
log.Println(err)
// chmodはできなくてもしかたないのでreturnしない
}
}
return nil
}
func Copy(srcFile, dstFile, owner, group, mode string) error {
var (
uid int
gid int
)
if owner == "" || group == "" {
uid = -1
gid = -1
} else {
u, err := user.Lookup(owner)
if err != nil {
log.Println(err)
return err
}
g, err := user.LookupGroup(group)
if err != nil {
log.Println(err)
return err
}
uid, err = strconv.Atoi(u.Uid)
if err != nil {
log.Println(err)
return err
}
gid, err = strconv.Atoi(g.Gid)
if err != nil {
log.Println(err)
return err
}
}
if mode == "" {
return cp(srcFile, dstFile, uid, gid)
}
m, err := strconv.ParseUint(mode, 8, 32)
if err != nil {
log.Println(err)
return err
}
return cp(srcFile, dstFile, uid, gid, os.FileMode(m))
}
func Backup(srcFile string) error {
var (
fi os.FileInfo
err error
)
// ファイルの有無判定。存在しなければ終了
fi, err = os.Stat(srcFile)
if err != nil {
return nil
}
var (
sys = fi.Sys()
uid = sys.(*syscall.Stat_t).Uid
gid = sys.(*syscall.Stat_t).Gid
m = fi.Mode()
)
now := time.Now().Format("2006-01-02_150405")
dstFile := fmt.Sprintf("%s.%s", srcFile, now)
return cp(srcFile, dstFile, int(uid), int(gid), m)
}