github.com/chwjbn/xclash@v0.2.0/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "os" 7 "os/signal" 8 "path/filepath" 9 "runtime" 10 "syscall" 11 12 "github.com/chwjbn/xclash/config" 13 C "github.com/chwjbn/xclash/constant" 14 "github.com/chwjbn/xclash/hub" 15 "github.com/chwjbn/xclash/hub/executor" 16 "github.com/chwjbn/xclash/log" 17 18 "go.uber.org/automaxprocs/maxprocs" 19 ) 20 21 var ( 22 flagset map[string]bool 23 version bool 24 testConfig bool 25 homeDir string 26 configFile string 27 externalUI string 28 externalController string 29 secret string 30 ) 31 32 func init() { 33 flag.StringVar(&homeDir, "d", "", "set configuration directory") 34 flag.StringVar(&configFile, "f", "", "specify configuration file") 35 flag.StringVar(&externalUI, "ext-ui", "", "override external ui directory") 36 flag.StringVar(&externalController, "ext-ctl", "", "override external controller address") 37 flag.StringVar(&secret, "secret", "", "override secret for RESTful API") 38 flag.BoolVar(&version, "v", false, "show current version of clash") 39 flag.BoolVar(&testConfig, "t", false, "test configuration and exit") 40 flag.Parse() 41 42 flagset = map[string]bool{} 43 flag.Visit(func(f *flag.Flag) { 44 flagset[f.Name] = true 45 }) 46 } 47 48 func main() { 49 maxprocs.Set(maxprocs.Logger(func(string, ...interface{}) {})) 50 if version { 51 fmt.Printf("Clash %s %s %s with %s %s\n", C.Version, runtime.GOOS, runtime.GOARCH, runtime.Version(), C.BuildTime) 52 return 53 } 54 55 if homeDir != "" { 56 if !filepath.IsAbs(homeDir) { 57 currentDir, _ := os.Getwd() 58 homeDir = filepath.Join(currentDir, homeDir) 59 } 60 C.SetHomeDir(homeDir) 61 } 62 63 if configFile != "" { 64 if !filepath.IsAbs(configFile) { 65 currentDir, _ := os.Getwd() 66 configFile = filepath.Join(currentDir, configFile) 67 } 68 C.SetConfig(configFile) 69 } else { 70 configFile := filepath.Join(C.Path.HomeDir(), C.Path.Config()) 71 C.SetConfig(configFile) 72 } 73 74 if err := config.Init(C.Path.HomeDir()); err != nil { 75 log.Fatalln("Initial configuration directory error: %s", err.Error()) 76 } 77 78 if testConfig { 79 if _, err := executor.Parse(); err != nil { 80 log.Errorln(err.Error()) 81 fmt.Printf("configuration file %s test failed\n", C.Path.Config()) 82 os.Exit(1) 83 } 84 fmt.Printf("configuration file %s test is successful\n", C.Path.Config()) 85 return 86 } 87 88 var options []hub.Option 89 if flagset["ext-ui"] { 90 options = append(options, hub.WithExternalUI(externalUI)) 91 } 92 if flagset["ext-ctl"] { 93 options = append(options, hub.WithExternalController(externalController)) 94 } 95 if flagset["secret"] { 96 options = append(options, hub.WithSecret(secret)) 97 } 98 99 if err := hub.Parse(options...); err != nil { 100 log.Fatalln("Parse config error: %s", err.Error()) 101 } 102 103 sigCh := make(chan os.Signal, 1) 104 signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) 105 <-sigCh 106 }