102 lines
2.6 KiB
Go
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
|
|
}
|