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  }