Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly Expand Appdata Directory #1508

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/asset/dcr/rpcwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
ukane-philemon marked this conversation as resolved.
Show resolved Hide resolved
certs, err := os.ReadFile(cert)
if err != nil {
return nil, fmt.Errorf("TLS certificate read error: %w", err)
}
Expand Down
25 changes: 13 additions & 12 deletions client/cmd/dexc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
ukane-philemon marked this conversation as resolved.
Show resolved Hide resolved
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{
ukane-philemon marked this conversation as resolved.
Show resolved Hide resolved
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.
Expand All @@ -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,
Expand Down
68 changes: 27 additions & 41 deletions dex/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "%") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only if os is windows.

Also, why prefix? What if user is doing something like C:\dexdata\%USERNAME%?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intended to expand %variable%\path
%USERNAME% will eventually expand to a full path C:\users\username. Currently, C:\dexdata\%USERNAME% will be handled by os.ExpandEnv. Will provide support for such cases.

// Split path into %VARIABLE% and path
pathArray := strings.SplitAfterN(path, "/", 2)
Copy link
Member

@chappjc chappjc Mar 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about "\" as a path separator?
The filepath package has methods and consts for this purpose.

dirEnv := strings.ToUpper(strings.Trim(pathArray[0], "%/"))
path = pathArray[1]
ukane-philemon marked this conversation as resolved.
Show resolved Hide resolved
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.
ukane-philemon marked this conversation as resolved.
Show resolved Hide resolved
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 = "."
}
Comment on lines -31 to 49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does look like a better option than parsing the file name looking for a user name.

I guess we lose the ability to expand to ~otheruser? I can't imagine when that would be used though. Actually seems like something we should not encourage, so I like this change.


return filepath.Join(homeDir, path)
return filepath.Join(dirName, path[1:])
}