diff --git a/client/asset/dcr/rpcwallet.go b/client/asset/dcr/rpcwallet.go index b0565e9dde..61605f56c3 100644 --- a/client/asset/dcr/rpcwallet.go +++ b/client/asset/dcr/rpcwallet.go @@ -149,7 +149,8 @@ func newRPCWallet(cfg *Config, chainParams *chaincfg.Params, logger dex.Logger) log: log, } - certs, err := os.ReadFile(cfg.RPCCert) + cert := dex.CleanAndExpandPath(cfg.RPCCert) + certs, err := os.ReadFile(cert) if err != nil { return nil, fmt.Errorf("TLS certificate read error: %w", err) } diff --git a/client/cmd/dexc/config.go b/client/cmd/dexc/config.go index 065579aafd..0df95dfb71 100644 --- a/client/cmd/dexc/config.go +++ b/client/cmd/dexc/config.go @@ -95,23 +95,25 @@ type Config struct { LocalLogs bool `long:"loglocal" description:"Use local time zone time stamps in log entries."` CPUProfile string `long:"cpuprofile" description:"File for CPU profiling."` HTTPProfile bool `long:"httpprof" description:"Start HTTP profiler on /pprof."` - ShowVer bool `short:"V" long:"version" description:"Display version information and exit"` + ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` TorProxy string `long:"torproxy" description:"Connect via TOR (eg. 127.0.0.1:9050)."` TorIsolation bool `long:"torisolation" description:"Enable TOR circuit isolation."` Net dex.Network CertHosts []string } -var defaultConfig = Config{ - AppData: defaultApplicationDirectory, - Config: defaultConfigPath, - DebugLevel: defaultLogLevel, - CertHosts: []string{defaultTestnetHost, defaultSimnetHost, - defaultMainnetHost}, -} - // configure processes the application configuration. func configure() (*Config, error) { + + // Default configuration + defaultConfig := Config{ + AppData: defaultApplicationDirectory, + Config: defaultConfigPath, + DebugLevel: defaultLogLevel, + CertHosts: []string{defaultTestnetHost, defaultSimnetHost, + defaultMainnetHost}, + } + // Pre-parse the command line options to see if an alternative config file // or the version flag was specified. Override any environment variables // with parsed command line flags. @@ -133,14 +135,13 @@ func configure() (*Config, error) { } // Show the version and exit if the version flag was specified. - if preCfg.ShowVer { + if preCfg.ShowVersion { fmt.Printf("%s version %s (Go version %s %s/%s)\n", version.AppName, version.Version(), runtime.Version(), runtime.GOOS, runtime.GOARCH) os.Exit(0) } - // If the app directory has been changed, replace shortcut chars such - // as "~" with the full path. + // Update the application directory if specified on CLI. if preCfg.AppData != defaultApplicationDirectory { preCfg.AppData = dex.CleanAndExpandPath(preCfg.AppData) // If the app directory has been changed, but the config file path hasn't, diff --git a/dex/path.go b/dex/path.go index cb1b1f1238..524cac5934 100644 --- a/dex/path.go +++ b/dex/path.go @@ -5,62 +5,48 @@ package dex import ( "os" - "os/user" "path/filepath" - "runtime" "strings" ) -// CleanAndExpandPath expands environment variables and leading ~ in the -// passed path, cleans the result, and returns it. +// CleanAndExpandPath expands environment variables and leading ~ in the passed +// path, cleans the result, and returns it. func CleanAndExpandPath(path string) string { // Nothing to do when no path is given. if path == "" { return path } - // NOTE: The os.ExpandEnv doesn't work with Windows cmd.exe-style - // %VARIABLE%, but the variables can still be expanded via POSIX-style - // $VARIABLE. - path = os.ExpandEnv(path) + dirName := "" + + // This supports Windows cmd.exe-style %VARIABLE%. + if strings.HasPrefix(path, "%") { + // Split path into %VARIABLE% and path + pathArray := strings.SplitAfterN(path, "/", 2) + dirEnv := strings.ToUpper(strings.Trim(pathArray[0], "%/")) + path = pathArray[1] + dirName = os.Getenv(dirEnv) + if dirName == "" { + // This does not support Windows XP and before as + // they didn't have a LOCALAPPDATA. + dirName = os.Getenv("LOCALAPPDATA") + } + return filepath.Join(dirName, path) + } if !strings.HasPrefix(path, "~") { + // NOTE: The os.ExpandEnv doesn't work with Windows cmd.exe-style + // %VARIABLE%, but the variables can still be expanded via POSIX-style + // $VARIABLE. + path = os.ExpandEnv(path) return filepath.Clean(path) } - // Expand initial ~ to the current user's home directory, or ~otheruser - // to otheruser's home directory. On Windows, both forward and backward - // slashes can be used. - path = path[1:] - - var pathSeparators string - if runtime.GOOS == "windows" { - pathSeparators = string(os.PathSeparator) + "/" - } else { - pathSeparators = string(os.PathSeparator) - } - - userName := "" - if i := strings.IndexAny(path, pathSeparators); i != -1 { - userName = path[:i] - path = path[i:] - } - - homeDir := "" - var u *user.User - var err error - if userName == "" { - u, err = user.Current() - } else { - u, err = user.Lookup(userName) - } - if err == nil { - homeDir = u.HomeDir - } - // Fallback to CWD if user lookup fails or user has no home directory. - if homeDir == "" { - homeDir = "." + dirName, err := os.UserHomeDir() + if err != nil { + // Fallback to CWD if retrieving user home directory fails. + dirName = "." } - return filepath.Join(homeDir, path) + return filepath.Join(dirName, path[1:]) }