-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
152 lines (138 loc) · 3.58 KB
/
main.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"flag"
"fmt"
"os"
"os/signal"
"os/user"
"path/filepath"
"syscall"
"time"
)
func main() {
// Initialize logging
SetupLogging()
// Parse command-line arguments
if len(os.Args) < 2 {
PrintHelp()
os.Exit(1)
}
command := os.Args[1]
// Default configuration path
configPath := filepath.Join(GetHomeDir(), ".dblock", "default.yaml")
// Command-line flags
fs := flag.NewFlagSet(command, flag.ExitOnError)
timeout := fs.Int("t", 0, "Timeout in minutes after which the operation is reversed")
configFile := fs.String("c", configPath, "Path to the configuration file")
// Parse flags
if err := fs.Parse(os.Args[2:]); err != nil {
logError(err)
os.Exit(1)
}
// Load configuration
config, err := LoadConfig(*configFile)
if err != nil {
logError(err)
fmt.Println("Error loading configuration:", err)
os.Exit(1)
}
// Check for root privileges when modifying the hosts file
if command == "enable" || command == "disable" {
if !isRoot() {
fmt.Println("Error: Insufficient permissions. Please run the command with 'sudo'.")
os.Exit(1)
}
}
switch command {
case "enable":
if err := EnableBlocking(config); err != nil {
logError(err)
fmt.Println("Error enabling blocking:", err)
os.Exit(1)
}
fmt.Println("Blocking enabled.")
if *timeout > 0 {
fmt.Printf("Blocking will be disabled in %d minutes.\n", *timeout)
// Create a channel to signal when the goroutine has finished
done := make(chan struct{})
// Start the goroutine
go func() {
time.Sleep(time.Duration(*timeout) * time.Minute)
if err := DisableBlocking(config); err != nil {
logError(err)
fmt.Println("Error disabling blocking after timeout:", err)
} else {
fmt.Println("Blocking disabled after timeout.")
}
// Signal that the goroutine has completed
close(done)
}()
// Wait for either the goroutine to finish or an interrupt signal
waitForCompletion(done)
}
case "disable":
if err := DisableBlocking(config); err != nil {
logError(err)
fmt.Println("Error disabling blocking:", err)
os.Exit(1)
}
fmt.Println("Blocking disabled.")
if *timeout > 0 {
fmt.Printf("Blocking will be re-enabled in %d minutes.\n", *timeout)
// Create a channel to signal when the goroutine has finished
done := make(chan struct{})
// Start the goroutine
go func() {
time.Sleep(time.Duration(*timeout) * time.Minute)
if err := EnableBlocking(config); err != nil {
logError(err)
fmt.Println("Error enabling blocking after timeout:", err)
} else {
fmt.Println("Blocking re-enabled after timeout.")
}
// Signal that the goroutine has completed
close(done)
}()
// Wait for either the goroutine to finish or an interrupt signal
waitForCompletion(done)
}
case "status":
status, err := GetStatus(config)
if err != nil {
logError(err)
fmt.Println("Error getting status:", err)
os.Exit(1)
}
fmt.Println("Blocking status:", status)
case "list":
ListDomains(config)
case "help":
PrintHelp()
default:
fmt.Println("Unknown command:", command)
PrintHelp()
os.Exit(1)
}
}
func isRoot() bool {
currentUser, err := user.Current()
if err != nil {
logError(err)
fmt.Println("Error determining current user:", err)
os.Exit(1)
}
return currentUser.Uid == "0"
}
func waitForCompletion(done chan struct{}) {
// Set up signal handling
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
select {
case <-done:
// Goroutine completed
os.Exit(0)
case sig := <-sigs:
fmt.Printf("\nReceived signal: %s. Exiting.\n", sig)
os.Exit(0)
}
}