Skip to content

Commit 3a90f4e

Browse files
author
DanArmor
committed
feat: alias system
1 parent b02dfb3 commit 3a90f4e

File tree

6 files changed

+907
-41
lines changed

6 files changed

+907
-41
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build:
2+
go build -o wakeonlan-go.out cmd/wakeonlan-go/wakeonlan-go.go

cmd/wakeonlan-go.go

Lines changed: 0 additions & 38 deletions
This file was deleted.

cmd/wakeonlan-go/wakeonlan-go.go

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
// The wakeonlan-go program is designed as easy WoL instrument
2+
package main
3+
4+
import (
5+
"bytes"
6+
"encoding/gob"
7+
"fmt"
8+
"os"
9+
"path/filepath"
10+
"strings"
11+
12+
"git.mills.io/prologic/bitcask"
13+
"github.com/jessevdk/go-flags"
14+
"github.com/kirsle/configdir"
15+
16+
"github.com/DanArmor/wakeonlan-go/pkg/wolpacket"
17+
"github.com/DanArmor/wakeonlan-go/pkg/wolrunner"
18+
"github.com/jedib0t/go-pretty/v6/table"
19+
)
20+
21+
var opts struct {
22+
Dest string `short:"d" description:"Destination address(port is optional)"`
23+
Local string `short:"l" description:"Local address of network interface (port is optional)"`
24+
Rec string `short:"r" description:"If used - action is not performed, but is recorded as alias to given name. If you use alias inside other alias - it will be deep copy, so you can delete used alias in the future."`
25+
Show bool `short:"s" description:"Show list of aliases"`
26+
Remove string `long:"rm" description:"Remove alias with a given name"`
27+
Positional struct {
28+
MACs []string
29+
} `positional-args:"yes" required:"yes" description:"MAC addresses of machines to wake up"`
30+
}
31+
32+
type WOLRecord struct {
33+
Local string
34+
Dest string
35+
Macs []string
36+
}
37+
38+
func (wolr *WOLRecord) GetDest() string {
39+
if wolr.Dest == "" {
40+
return "Default"
41+
} else {
42+
return wolr.Dest
43+
}
44+
}
45+
46+
func (wolr *WOLRecord) GetLocal() string {
47+
if wolr.Local == "" {
48+
return "Default"
49+
} else {
50+
return wolr.Local
51+
}
52+
}
53+
54+
func main() {
55+
// Setup config file
56+
configPath := configdir.LocalConfig("wakeonlan-go")
57+
if err := configdir.MakePath(configPath); err != nil {
58+
fmt.Print("Error:", err)
59+
return
60+
}
61+
configFile := filepath.Join(configPath, "config.db")
62+
63+
db, err := bitcask.Open(configFile)
64+
if err != nil {
65+
fmt.Print("Error:", err)
66+
return
67+
}
68+
defer db.Close()
69+
70+
if _, err := flags.Parse(&opts); err != nil {
71+
fmt.Print("Error:", err)
72+
return
73+
}
74+
75+
if opts.Show {
76+
ch := db.Keys()
77+
index := 1
78+
t := table.NewWriter()
79+
t.SetOutputMirror(os.Stdout)
80+
t.AppendHeader(table.Row{"#", "Aliase", "Local", "Dest", "MACs"})
81+
for k := range ch {
82+
v, err := db.Get(k)
83+
if err != nil {
84+
fmt.Print("Error:", err)
85+
return
86+
}
87+
buf := &bytes.Buffer{}
88+
buf.Write(v)
89+
var record WOLRecord
90+
decoder := gob.NewDecoder(buf)
91+
if err := decoder.Decode(&record); err != nil {
92+
fmt.Print("Error:", err)
93+
return
94+
}
95+
t.AppendRow(table.Row{index, string(k), record.GetLocal(), record.GetDest(), strings.Join(record.Macs, "\n")})
96+
index++
97+
}
98+
t.SetStyle(table.StyleColoredYellowWhiteOnBlack)
99+
t.Render()
100+
return
101+
}
102+
103+
if opts.Remove != "" {
104+
ch := db.Keys()
105+
for k := range ch {
106+
if string(k) == opts.Remove {
107+
db.Delete(k)
108+
fmt.Print("Alias is deleted\n")
109+
return
110+
}
111+
}
112+
fmt.Print("No such alias\n")
113+
return
114+
}
115+
116+
if len(opts.Positional.MACs) == 0 {
117+
fmt.Print("Please, provide MAC addresses or aliases!")
118+
return
119+
}
120+
121+
if opts.Rec != "" {
122+
// Make a record
123+
// Let's find other aliases in list of macs
124+
var addrs []string
125+
for _, v := range opts.Positional.MACs {
126+
addr, err := wolpacket.NewMACAddress(v)
127+
if err != nil {
128+
buf := &bytes.Buffer{}
129+
recordData, err := db.Get(addr[:])
130+
if err != nil {
131+
fmt.Print("Error:", err)
132+
return
133+
}
134+
buf.Write(recordData)
135+
var record WOLRecord
136+
decoder := gob.NewDecoder(buf)
137+
if err := decoder.Decode(&record); err != nil {
138+
fmt.Print("Error:", err)
139+
return
140+
}
141+
addrs = append(addrs, record.Macs...)
142+
} else {
143+
addrs = append(addrs, v)
144+
}
145+
}
146+
buf := &bytes.Buffer{}
147+
record := WOLRecord{
148+
Local: opts.Local,
149+
Dest: opts.Dest,
150+
Macs: addrs,
151+
}
152+
encoder := gob.NewEncoder(buf)
153+
if err := encoder.Encode(&record); err != nil {
154+
fmt.Print("Error:", err)
155+
return
156+
}
157+
db.Put([]byte(opts.Rec), buf.Bytes())
158+
} else {
159+
// Send WoL
160+
addrs := make([]WOLRecord, 1)
161+
addrs[0].Local = opts.Local
162+
addrs[0].Dest = opts.Dest
163+
for _, v := range opts.Positional.MACs {
164+
_, err := wolpacket.NewMACAddress(v)
165+
if err != nil {
166+
buf := &bytes.Buffer{}
167+
recordData, err := db.Get([]byte(v))
168+
if err != nil {
169+
panic(err)
170+
}
171+
buf.Write(recordData)
172+
var record WOLRecord
173+
decoder := gob.NewDecoder(buf)
174+
if err := decoder.Decode(&record); err != nil {
175+
panic(err)
176+
}
177+
addrs = append(addrs, record)
178+
} else {
179+
addrs[0].Macs = append(addrs[0].Macs, v)
180+
}
181+
}
182+
index := 0
183+
if len(addrs[0].Macs) == 0 {
184+
index = 1
185+
}
186+
count := 1
187+
for index < len(addrs) {
188+
wolr, err := wolrunner.NewWOLRunner(addrs[index].Local, addrs[index].Dest)
189+
if err != nil {
190+
fmt.Print("Error:", err)
191+
return
192+
}
193+
for i := range addrs[index].Macs {
194+
if err := wolr.WakeMAC(addrs[index].Macs[i]); err != nil {
195+
fmt.Print("Error:", err)
196+
return
197+
} else {
198+
fmt.Printf("#%d WoL packet was send to %s successfully. Local: %s, Dest: %s\n", count, addrs[index].Macs[i], wolr.LocalUDP().String(), wolr.DestinationUDP().String())
199+
}
200+
}
201+
index++
202+
count++
203+
}
204+
}
205+
}

go.mod

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ module github.com/DanArmor/wakeonlan-go
33
go 1.19
44

55
require (
6+
git.mills.io/prologic/bitcask v1.0.2 // indirect
7+
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 // indirect
8+
github.com/gofrs/flock v0.8.0 // indirect
9+
github.com/jedib0t/go-pretty v4.3.0+incompatible // indirect
10+
github.com/jedib0t/go-pretty/v6 v6.4.6 // indirect
611
github.com/jessevdk/go-flags v1.5.0 // indirect
12+
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f // indirect
13+
github.com/mattn/go-runewidth v0.0.13 // indirect
14+
github.com/pkg/errors v0.9.1 // indirect
15+
github.com/plar/go-adaptive-radix-tree v1.0.4 // indirect
16+
github.com/rivo/uniseg v0.2.0 // indirect
17+
github.com/sirupsen/logrus v1.8.1 // indirect
18+
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85 // indirect
719
golang.org/x/sys v0.4.0 // indirect
820
)

0 commit comments

Comments
 (0)