diff --git a/main.go b/main.go index c8174bf..ad5e26d 100644 --- a/main.go +++ b/main.go @@ -3,27 +3,51 @@ package main import ( "context" "flag" + "fmt" + "os" + "os/exec" + "os/signal" + "path/filepath" + "strings" + "time" + "github.com/unchainese/unchain/global" "github.com/unchainese/unchain/server" - "os" - "os/signal" - "time" ) -var configFilePath, installMode, action string +var configFilePath string + +func init() { + flag.StringVar(&configFilePath, "config", "config.toml", "配置文件路径") +} func main() { - flag.StringVar(&action, "action", "run", "动作参数,可选值: run, install,uninstall,info,client") - flag.StringVar(&configFilePath, "config", "config.toml", "配置文件路径") - flag.StringVar(&installMode, "mode", "single", "安装命令的模式参数") flag.Parse() - //todo:: switch case command - if action == "client" { - server.StartSocks5Server() - return + // Parse subcommands + args := flag.Args() + if len(args) == 0 { + args = append(args, "run") // default to "run" if no subcommand is provided } + subcommand := strings.ToLower(args[0]) + switch subcommand { + case "run": + runServer() + case "install": + installService() + case "client": + runClient() + case "help", "-h", "--help": + printHelp() + default: + fmt.Printf("Unknown subcommand: %s\n\n", subcommand) + printHelp() + os.Exit(1) + } +} + +func runServer() { c := global.Cfg(configFilePath) //using default config.toml file fd := global.SetupLogger(c) defer fd.Close() @@ -40,5 +64,88 @@ func main() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() app.Shutdown(ctx) - +} + +func installService() { + // Check if systemctl is available + cmd := exec.Command("systemctl", "--version") + if err := cmd.Run(); err != nil { + fmt.Println("systemctl is not available on this system") + return + } + + // Get the executable path + exe, err := os.Executable() + if err != nil { + fmt.Printf("Failed to get executable path: %v\n", err) + return + } + + dir := filepath.Dir(exe) + + // Service file content + content := fmt.Sprintf(`[Unit] +Description=Vless over Websocket Proxy +After=network.target + +[Service] +ExecStart=%s +Restart=always +User=root +WorkingDirectory=%s + +[Install] +WantedBy=multi-user.target +`, exe, dir) + + // Write the service file + servicePath := "/etc/systemd/system/unchain.service" + err = os.WriteFile(servicePath, []byte(content), 0644) + if err != nil { + fmt.Printf("Failed to write service file to %s: %v\n", servicePath, err) + return + } + + fmt.Printf("Service file created at %s\n", servicePath) + + // Reload systemd + if err := exec.Command("systemctl", "daemon-reload").Run(); err != nil { + fmt.Printf("Failed to reload systemd: %v\n", err) + return + } + + // Enable the service + if err := exec.Command("systemctl", "enable", "unchain").Run(); err != nil { + fmt.Printf("Failed to enable service: %v\n", err) + return + } + + // Start the service + if err := exec.Command("systemctl", "start", "unchain").Run(); err != nil { + fmt.Printf("Failed to start service: %v\n", err) + return + } + + fmt.Println("Service installed and started successfully") +} + +func runClient() { + fmt.Println("Starting SOCKS5 client...") + server.StartSocks5Server() +} + +func printHelp() { + fmt.Println("Unchain - A VLESS over WebSocket proxy server") + fmt.Println() + fmt.Println("Usage:") + fmt.Println(" unchain [subcommand] [flags]") + fmt.Println() + fmt.Println("Subcommands:") + fmt.Println(" run Run the server (default)") + fmt.Println(" install Install the service") + fmt.Println(" client Run as SOCKS5 server as VPN client") + fmt.Println(" help Show this help message") + fmt.Println() + fmt.Println("Flags:") + flag.PrintDefaults() }