-
Notifications
You must be signed in to change notification settings - Fork 0
/
utimescmd.go
97 lines (82 loc) · 2.56 KB
/
utimescmd.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
package commands
import (
"errors"
"fmt"
"github.com/cpssd/paranoid/libpfs/returncodes"
"os"
"path"
"syscall"
"time"
)
//UtimesCommand updates the acess time and modified time of a file
func UtimesCommand(paranoidDirectory, filePath string, atime, mtime *time.Time) (returnCode returncodes.Code, returnError error) {
Log.Info("utimes command called")
Log.Verbose("utimes : given paranoidDirectory = " + paranoidDirectory)
err := GetFileSystemLock(paranoidDirectory, SharedLock)
if err != nil {
return returncodes.EUNEXPECTED, err
}
defer func() {
err := UnLockFileSystem(paranoidDirectory)
if err != nil {
returnCode = returncodes.EUNEXPECTED
returnError = err
}
}()
namepath := getParanoidPath(paranoidDirectory, filePath)
fileType, err := getFileType(paranoidDirectory, namepath)
if err != nil {
return returncodes.EUNEXPECTED, err
}
if fileType == typeENOENT {
return returncodes.ENOENT, errors.New(filePath + " does not exist")
}
fileInodeBytes, code, err := getFileInode(namepath)
if code != returncodes.OK {
return code, err
}
inodeName := string(fileInodeBytes)
err = getFileLock(paranoidDirectory, inodeName, ExclusiveLock)
if err != nil {
return returncodes.EUNEXPECTED, err
}
defer func() {
err := unLockFile(paranoidDirectory, inodeName)
if err != nil {
returnCode = returncodes.EUNEXPECTED
returnError = err
}
}()
file, err := os.Open(path.Join(paranoidDirectory, "contents", inodeName))
if err != nil {
return returncodes.EUNEXPECTED, fmt.Errorf("error opening contents file: %s", err)
}
defer file.Close()
fi, err := file.Stat()
if err != nil {
return returncodes.EUNEXPECTED, fmt.Errorf("error stating file: %s", err)
}
stat := fi.Sys().(*syscall.Stat_t)
oldatime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
oldmtime := fi.ModTime()
if atime == nil && mtime == nil {
return returncodes.EUNEXPECTED, errors.New("no times to update!")
}
if atime == nil {
err = os.Chtimes(path.Join(paranoidDirectory, "contents", inodeName), oldatime, *mtime)
if err != nil {
return returncodes.EUNEXPECTED, fmt.Errorf("error changing times: %s", err)
}
} else if mtime == nil {
err = os.Chtimes(path.Join(paranoidDirectory, "contents", inodeName), *atime, oldmtime)
if err != nil {
return returncodes.EUNEXPECTED, fmt.Errorf("error changing times: %s", err)
}
} else {
err = os.Chtimes(path.Join(paranoidDirectory, "contents", inodeName), *atime, *mtime)
if err != nil {
return returncodes.EUNEXPECTED, fmt.Errorf("error changing times: %s", err)
}
}
return returncodes.OK, nil
}