Files

102 lines
2.6 KiB
Go

package main
import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"golang.org/x/term"
"linkport/internal/buildinfo"
"linkport/internal/desktop"
"linkport/internal/gateway"
"linkport/internal/protocol"
"linkport/internal/store"
)
func main() {
if err := run(); err != nil {
log.Print(err)
if desktop.Enabled() && len(os.Args) == 1 && term.IsTerminal(int(os.Stdin.Fd())) {
fmt.Println("启动失败。请查看以上错误;按 Enter 关闭窗口。")
fmt.Scanln()
}
os.Exit(1)
}
}
func run() error {
if handled, err := runStandaloneCommand(os.Args[1:]); handled {
return err
}
if len(os.Args) == 1 {
log.Print(startupBanner)
}
log.Print(buildinfo.Current().String())
var maintenance maintenanceCommand
if len(os.Args) > 1 {
maintenance = maintenanceCommands[os.Args[1]]
if len(os.Args) != 2 || maintenance == nil {
return fmt.Errorf("usage: linkport [version|data-path|reset-password|migrate-data|migrate-key|export-ca]")
}
}
prepared, err := desktop.Prepare()
if err != nil {
return err
}
defer prepared.Close()
path := prepared.Data
logFile, logErr := os.OpenFile(filepath.Join(filepath.Dir(path), "linkport.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
if logErr != nil {
return fmt.Errorf("open log file: %w", logErr)
}
defer logFile.Close()
log.SetOutput(io.MultiWriter(os.Stderr, logFile))
var local *desktop.Config
if desktop.Enabled() {
local = prepared
}
log.Printf("SQLite: %s", path)
legacyKey := func() (string, error) { return desktop.ReadLegacyKey(path) }
migrateKey := len(os.Args) == 2 && os.Args[1] == "migrate-key"
if migrateKey {
legacyKey = func() (string, error) {
fmt.Print("Original legacy key (one-time migration): ")
key, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Println()
return strings.TrimSpace(string(key)), err
}
}
s, err := store.OpenPortable(path, legacyKey)
if err != nil {
return err
}
defer s.Close()
if maintenance != nil {
return maintenance(s, path)
}
authEnabled := strings.EqualFold(os.Getenv("LINKPORT_AUTH_ENABLED"), "true")
if (authEnabled && local == nil) || os.Getenv("LINKPORT_ADMIN_PASSWORD") != "" {
if err = s.InitAdmin(os.Getenv("LINKPORT_ADMIN_USER"), os.Getenv("LINKPORT_ADMIN_PASSWORD")); err != nil {
return err
}
}
tlsConfig, err := gatewayTLS(s, path)
if err != nil {
return err
}
m := gateway.New(s, tlsConfig, protocol.NewHandlers())
defer m.Shutdown()
if err := restoreGateways(s, m); err != nil {
return err
}
return runManagement(s, m, local, authEnabled)
}
func env(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}