105 lines
2.4 KiB
Go
105 lines
2.4 KiB
Go
//go:build darwin
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"os/signal"
|
|
"path/filepath"
|
|
"syscall"
|
|
"time"
|
|
|
|
"vpnclient/internal/apphost"
|
|
"vpnclient/internal/config"
|
|
"vpnclient/internal/core"
|
|
"vpnclient/internal/update"
|
|
)
|
|
|
|
func main() {
|
|
if update.MaybeFinishUpdate(os.Args[1:]) {
|
|
return
|
|
}
|
|
update.CleanupStaleDownloads()
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
|
|
cfgPath, err := config.LocateConfig()
|
|
if err != nil {
|
|
fatalf("Не удалось найти путь конфига: %v", err)
|
|
}
|
|
if _, err := os.Stat(cfgPath); os.IsNotExist(err) {
|
|
if err := config.WriteExample(cfgPath); err != nil {
|
|
fatalf("Не удалось создать конфиг: %v", err)
|
|
}
|
|
}
|
|
cfg, err := config.Load(cfgPath)
|
|
if err != nil {
|
|
fatalf("Ошибка конфига %s: %v", cfgPath, err)
|
|
}
|
|
logBuf := &bytes.Buffer{}
|
|
mgr, err := core.NewManager(cfgPath, cfg, logBuf)
|
|
if err != nil {
|
|
fatalf("%v", err)
|
|
}
|
|
|
|
a := apphost.New(mgr, cfgPath, logBuf)
|
|
a.OpenURL = func(u string) error {
|
|
return exec.Command("open", u).Start()
|
|
}
|
|
a.OnAfterUpdate = func() {
|
|
go func() {
|
|
time.Sleep(300 * time.Millisecond)
|
|
os.Exit(0)
|
|
}()
|
|
}
|
|
|
|
ln, uiURL, err := apphost.ListenLocal()
|
|
if err != nil {
|
|
fatalf("listen: %v", err)
|
|
}
|
|
srv := &http.Server{Handler: a.Handler()}
|
|
go func() {
|
|
_ = srv.Serve(ln)
|
|
}()
|
|
go a.AutoCheckUpdate()
|
|
|
|
if err := openAppWindow(uiURL); err != nil {
|
|
log.Printf("open UI: %v — откройте вручную: %s", err, uiURL)
|
|
fmt.Println(uiURL)
|
|
} else {
|
|
log.Printf("Navis UI: %s", uiURL)
|
|
}
|
|
|
|
sig := make(chan os.Signal, 1)
|
|
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
|
<-sig
|
|
_ = mgr.Disconnect()
|
|
_ = srv.Close()
|
|
}
|
|
|
|
func openAppWindow(uiURL string) error {
|
|
// Prefer Chromium-based --app window (looks like a desktop client).
|
|
for _, app := range []string{"Google Chrome", "Chromium", "Microsoft Edge", "Brave Browser", "Arc"} {
|
|
cmd := exec.Command("open", "-na", app, "--args", "--app="+uiURL, "--new-window")
|
|
if err := cmd.Start(); err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
// Fallback: default browser
|
|
return exec.Command("open", uiURL).Start()
|
|
}
|
|
|
|
func fatalf(format string, args ...any) {
|
|
msg := fmt.Sprintf(format, args...)
|
|
log.Println(msg)
|
|
_ = exec.Command("osascript", "-e", fmt.Sprintf(`display alert "Navis" message %q`, msg)).Run()
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Ensure we keep a reference for potential future dock icon path helpers.
|
|
var _ = filepath.Separator
|