package main import ( "errors" "kdelsd/afterlock" "kdelsd/config" "kdelsd/lockfile" "kdelsd/xdg/display" "kdelsd/xdg/keypressdetector" "kdelsd/xdg/lockscreen" "kdelsd/xdg/xinput_devnodes" "log" "os" "os/signal" "runtime/debug" "syscall" ) type afterLockConfig struct { INITIAL_DELAY int `optional` LOOP_DELAY int `optional` LOCK_PATH string `optional` LOG_PATH string PRINT_STACKTRACES bool `optional` } var configuration = afterLockConfig{ INITIAL_DELAY: 3, LOOP_DELAY: 7, LOCK_PATH: "/tmp/after-lock.lock", PRINT_STACKTRACES: true, } var mainDone chan bool var cleanupDone chan bool var sig chan os.Signal func init() { mainDone = make(chan bool) cleanupDone = make(chan bool) sig = make(chan os.Signal) } func main() { defer handleErrors() err := config.NewBuilder().Build("AFL_", &configuration) if err != nil { panic(err) } f := initLogging(configuration.LOG_PATH) if f == nil { panic("Failed to open logfile") } initCleanup(grabExclusiveProcessLock(configuration.LOCK_PATH), f) al := buildAfterlock() al.Start() mainDone<-true <-cleanupDone } func handleErrors() { if err := recover(); err != nil { log.Printf("Crashed with unexpected error: %v!\n", err) if configuration.PRINT_STACKTRACES { log.Printf("Stack trace:\n\n") debug.PrintStack() } os.Exit(1) } } func grabExclusiveProcessLock(lockfile_path string) *lockfile.Lockfile { lf := lockfile.New(lockfile_path) err := lf.Lock() if err != nil { panic(err) } return lf } func initCleanup(lock *lockfile.Lockfile, logfile *os.File) { signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) go func() { select{ case <-mainDone: case <-sig: } lock.Unlock() teardownLogging(logfile) cleanupDone<-true }() } func buildAfterlock() *afterlock.AfterLock { al := afterlock.New(getKeyboardDevNode()) al.InitialDelay = uint(configuration.INITIAL_DELAY) al.LoopDelay = uint(configuration.LOOP_DELAY) al.Display = display.Xset{} al.LockScreen = lockscreen.XDG{} al.KeypressDetector = keypressdetector.Evdev{} return al } func getKeyboardDevNode() string { devNode := xinput_devnodes.FindKeyboardDevNode() if devNode == "" { panic(errors.New("unable to find keyboard device node")) } return devNode }