forked from kryptco/kr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnotify.go
103 lines (93 loc) · 2.09 KB
/
notify.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
package kr
import (
"bufio"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
const NOTIFY_LOG_FILE_NAME = "krd-notify.log"
type Notifier struct {
*os.File
*sync.Mutex
}
func OpenNotifier(id string) (n Notifier, err error) {
filePath, err := NotifyDirFile(NOTIFY_LOG_FILE_NAME + "-" + id)
if err != nil {
return
}
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
return
}
n = Notifier{file, &sync.Mutex{}}
return
}
func (n Notifier) Notify(body []byte) (err error) {
n.Lock()
defer n.Unlock()
_, err = n.Write(body)
if err != nil {
return
}
err = n.Sync()
// FIXME: workaround to ensure success logged to stderr before signature returned to SSH
<-time.After(50 * time.Millisecond)
return
}
type NotificationReader struct {
*os.File
lineReader *bufio.Reader
}
func OpenNotificationReader(id string) (r NotificationReader, err error) {
filePath, err := NotifyDirFile(NOTIFY_LOG_FILE_NAME + "-" + id)
if err != nil {
return
}
file, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_APPEND|os.O_RDONLY, 0666)
if err != nil {
return
}
// some systems don't truncate correctly
// 2 = io.Seekend, but not added until Go 1.7
file.Seek(0, 2)
r = NotificationReader{
File: file,
lineReader: bufio.NewReader(file),
}
return
}
func (r NotificationReader) Read() (body []byte, err error) {
return r.lineReader.ReadBytes('\n')
}
func StartNotifyCleanup() {
go func() {
for {
notifyDir, err := NotifyDir()
if err == nil {
notifyDirFile, err := os.Open(notifyDir)
if err == nil {
names, err := notifyDirFile.Readdirnames(0)
if err == nil {
for _, name := range names {
if strings.HasSuffix(name, "]") {
logFilePath := filepath.Join(notifyDir, name)
logFile, err := os.Open(logFilePath)
if err == nil {
info, err := logFile.Stat()
if err == nil {
if time.Now().Sub(info.ModTime()) >= time.Hour {
_ = os.Remove(logFilePath)
}
}
}
}
}
}
}
}
<-time.After(1 * time.Hour)
}
}()
}