...
1 package udev
2
3 import (
4 "bytes"
5 "errors"
6 "io"
7 "strings"
8 "time"
9 )
10
11
12 const MaxSize = 4096
13
14
15 type Event string
16
17 const (
18 Action Event = "ACTION"
19 SequenceNumber Event = "SEQNUM"
20 SubSystem Event = "SUBSYSTEM"
21 SysPath Event = "DEVPATH"
22 DevName Event = "DEVNAME"
23 Major Event = "MAJOR"
24 Minor Event = "MINOR"
25 )
26
27
28 type ActionType string
29
30 const (
31 AddAction ActionType = "add"
32 RemoveAction ActionType = "remove"
33 ChangeAction ActionType = "change"
34 BindAction ActionType = "bind"
35 UnbindAction ActionType = "unbind"
36 )
37
38 const (
39 UdevEvent = "UDEV"
40 KernelEvent = "KERNEL"
41 magicNumber = "libudev\x00"
42 )
43
44 type EventType string
45
46 type UEvent struct {
47 Action ActionType
48 SequenceNumber string
49 EventType string
50 SubSystem string
51 SysPath string
52 DevName string
53 Major string
54 Minor string
55 Timestamp time.Time
56
57
58 EnvVars map[string]string
59 data *[]byte
60 }
61
62
63 func FromBuffer(b *bytes.Buffer) *UEvent {
64 data := b.Bytes()
65 return &UEvent{
66 EnvVars: map[string]string{},
67 data: &data,
68 Timestamp: time.Now(),
69 }
70 }
71
72 func (ue *UEvent) FromBytes(kvBytes []byte) *UEvent {
73 kv := strings.Replace(string(kvBytes), "\u0001", "", -1)
74 kv = strings.Replace(kv, "\u0010", "", -1)
75
76 i := strings.Index(kv, "=")
77 if i < 0 {
78
79 return ue
80 }
81
82
83 k, v := kv[:i], kv[i+1:len(kv)-1]
84 ue.EnvVars[k] = v
85
86
87 switch Event(k) {
88 case Action:
89 ue.Action = ActionType(v)
90 case SubSystem:
91 ue.SubSystem = v
92 case SysPath:
93 ue.SysPath = v
94 case Major:
95 ue.Major = v
96 case Minor:
97 ue.Minor = v
98 case DevName:
99 ue.DevName = v
100 case SequenceNumber:
101 ue.SequenceNumber = v
102 }
103 return ue
104 }
105
106 func (ue *UEvent) ToBytes() *[]byte {
107 return ue.data
108 }
109
110
111 func Decode(buf []byte) (ue *UEvent, err error) {
112 dataBuffer := bytes.NewBuffer(bytes.Clone(buf))
113 ue = FromBuffer(dataBuffer)
114 ue.EventType = KernelEvent
115
116 loop:
117 for {
118 kvBytes, err := dataBuffer.ReadBytes(0x00)
119 if errors.Is(err, io.EOF) || len(kvBytes) == 0 {
120 break loop
121 }
122 if err != nil {
123 return ue, err
124 }
125
126
127 if string(kvBytes) == magicNumber {
128 ue.EventType = UdevEvent
129 }
130
131
132 ue = ue.FromBytes(kvBytes)
133 }
134 return ue, nil
135 }
136
View as plain text