66 lines
1.3 KiB
Go
66 lines
1.3 KiB
Go
package cli
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
type RoutesUpdateDeps struct {
|
|
LockFile string
|
|
Update func(iface string) (ok bool, message string)
|
|
Stdout io.Writer
|
|
Stderr io.Writer
|
|
}
|
|
|
|
func RunRoutesUpdate(args []string, deps RoutesUpdateDeps) int {
|
|
if deps.Update == nil || deps.LockFile == "" {
|
|
return 1
|
|
}
|
|
stdout := deps.Stdout
|
|
if stdout == nil {
|
|
stdout = os.Stdout
|
|
}
|
|
stderr := deps.Stderr
|
|
if stderr == nil {
|
|
stderr = os.Stderr
|
|
}
|
|
|
|
fs := flag.NewFlagSet("routes-update", flag.ContinueOnError)
|
|
fs.SetOutput(stderr)
|
|
iface := fs.String("iface", "", "VPN interface (empty/auto = detect active)")
|
|
if err := fs.Parse(args); err != nil {
|
|
return 2
|
|
}
|
|
|
|
lock, err := os.OpenFile(deps.LockFile, os.O_CREATE|os.O_RDWR, 0o644)
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "lock open error: %v\n", err)
|
|
return 1
|
|
}
|
|
defer lock.Close()
|
|
|
|
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
|
|
fmt.Fprintln(stdout, "routes update already running")
|
|
return 0
|
|
}
|
|
defer func() {
|
|
_ = syscall.Flock(int(lock.Fd()), syscall.LOCK_UN)
|
|
}()
|
|
|
|
ok, message := deps.Update(*iface)
|
|
if ok {
|
|
fmt.Fprintln(stdout, strings.TrimSpace(message))
|
|
return 0
|
|
}
|
|
msg := strings.TrimSpace(message)
|
|
if msg == "" {
|
|
msg = "routes update failed"
|
|
}
|
|
fmt.Fprintln(stderr, msg)
|
|
return 1
|
|
}
|