-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
145 lines (125 loc) · 3.76 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
/*
* Copyright (c) 2013, 2022, 2024 Vadim Vygonets <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// UPower/Systemd Screen Saving Sleep Reactor
package main
import (
"errors"
"flag"
"io"
"log"
"os"
"strconv"
"time"
)
var conf = struct {
cmd []string
delay time.Duration
bg bool
debug bool
logLevel int
}{
logLevel: 1,
delay: defaultDelay,
}
// logging
func loglnAt(ll int, v ...interface{}) {
if conf.logLevel >= ll {
log.Println(v...)
}
}
func logln(v ...interface{}) { loglnAt(1, v...) }
func debugln(v ...interface{}) { loglnAt(2, v...) }
// command line flags
type durFlag struct{ *time.Duration }
func (d durFlag) String() string {
if d.Duration != nil {
return d.Duration.String()
}
return ""
}
func (d durFlag) Set(s string) error {
if f, err := strconv.ParseFloat(s, 64); err == nil {
*d.Duration = time.Duration(f * float64(time.Second))
// overflow results in -1<<63; handled below
} else if *d.Duration, err = time.ParseDuration(s); err != nil {
return err
}
if *d.Duration < 0 {
return errors.New("invalid duration")
}
return nil
}
func printHelp(long bool) {
w := flag.CommandLine.Output()
if long {
io.WriteString(w,
`USSSSR - UPower/Systemd Screen Saving Sleep Reactor
USSSSR runs a command when a UPower or systemd sleep (suspend,
hibernate) event is received on D-Bus.
When a sleep signal is received, if the command is not running,
it is started. If a foreground command exits with status 0
before the timeout, or a background command is started, the sleep
inhibit lock is released after a delay to let the screen saver
engage before sleep. Otherwise the lock is released immediately.
A screen saver that doesn't fork or exit until the screen is
unlocked (such as "slock") should be run in the background, a
command that exits immediately (such as "xset s activate" or
"xscreensaver -lock") in the foreground.
Delay can be specified in seconds (e.g., "0.5") or in any format
accepted by time.ParseDuration (e.g., "500ms").
`)
}
io.WriteString(w, "Usage:\n ")
io.WriteString(w, os.Args[0])
io.WriteString(w, " [flags] command [argument ...]\n\nFlags:\n")
flag.PrintDefaults()
}
func help(long bool) {
flag.CommandLine.SetOutput(os.Stdout)
printHelp(long)
os.Exit(0)
}
func usage() {
os.Stderr.WriteString("\n")
printHelp(false)
}
func parseFlags() {
flag.Var(durFlag{&conf.delay}, "d", "`delay` after command")
flag.BoolVar(&conf.bg, "b", false, "run command in the background")
flag.BoolVar(&conf.debug, "debug", false,
"use debug backend (non-functional)")
flag.BoolFunc("q", "quiet",
func(string) error { conf.logLevel--; return nil })
flag.BoolFunc("v", "verbose",
func(string) error { conf.logLevel++; return nil })
flag.BoolFunc("h", "short help",
func(string) error { help(false); return nil })
flag.BoolFunc("help", "long help",
func(string) error { help(true); return nil })
flag.Usage = usage
flag.Parse()
conf.cmd = flag.Args()
if len(conf.cmd) == 0 {
printHelp(false)
os.Exit(2)
}
}
func main() {
log.SetFlags(log.LstdFlags | log.Lmsgprefix)
log.SetPrefix("ussssr: ")
parseFlags()
loop()
}