//go:build windows package main import ( "encoding/json" "fmt" "os" "path/filepath" "github.com/pkg/errors" "github.com/urfave/cli" ) var configCommand = cli.Command{ Name: "config", Usage: "Information on the ncproxy config", Subcommands: []cli.Command{ { Name: "default", Usage: "Print the output of the default config to stdout or to a file", Flags: []cli.Flag{ cli.StringFlag{ Name: "file", Usage: "Output config to a file", }, }, Action: func(context *cli.Context) error { file := context.String("file") configData, err := json.MarshalIndent(defaultConfig(), "", " ") if err != nil { return errors.Wrap(err, "failed to marshal ncproxy config to json") } if file != "" { // Make the directory if it doesn't exist. if _, err := os.Stat(filepath.Dir(file)); err != nil { if err := os.MkdirAll(filepath.Dir(file), 0700); err != nil { return errors.Wrap(err, "failed to make path to config file") } } if err := os.WriteFile( file, []byte(configData), 0700, ); err != nil { return err } } else { fmt.Fprint(os.Stdout, string(configData)) } return nil }, }, }, } // defaultConfig generates a default ncproxy configuration file with every config option filled in. func defaultConfig() *config { return &config{ TTRPCAddr: "\\\\.\\pipe\\ncproxy-ttrpc", GRPCAddr: "127.0.0.1:6669", NodeNetSvcAddr: "127.0.0.1:6668", Timeout: 10, } } type config struct { TTRPCAddr string `json:"ttrpc,omitempty"` GRPCAddr string `json:"grpc,omitempty"` NodeNetSvcAddr string `json:"node_net_svc_addr,omitempty"` // Timeout in seconds to wait to connect to a NodeNetworkService. // 0 represents no timeout and ncproxy will continuously try and connect in the // background. Timeout uint32 `json:"timeout,omitempty"` } // Returns config. If path is "" will check the default location of the config // which is /path/of/executable/ncproxy.json func loadConfig(path string) (*config, error) { // Check if config path was passed in. if path != "" { return readConfig(path) } // Otherwise check if config is in default location (same dir as executable) if path, exists := configPresent(); exists { return readConfig(path) } return nil, errors.New("no config specified and no config found in current directory. Run `ncproxy config default` to generate a default config") } // Reads config from path and returns config struct if path is valid and marshaling // succeeds func readConfig(path string) (*config, error) { data, err := os.ReadFile(path) if err != nil { return nil, errors.Wrap(err, "failed to read config file") } conf := &config{} if err := json.Unmarshal(data, conf); err != nil { return nil, errors.New("failed to unmarshal config data") } return conf, nil } // Checks to see if there is an ncproxy.json in the directory of the executable. func configPresent() (string, bool) { path := filepath.Join(filepath.Dir(os.Args[0]), "ncproxy.json") if _, err := os.Stat(path); os.IsNotExist(err) { return "", false } return path, true }