// Copyright (c) 2013-2014 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package btcutil import ( "os" "os/user" "path/filepath" "runtime" "strings" "unicode" ) // appDataDir returns an operating system specific directory to be used for // storing application data for an application. See AppDataDir for more // details. This unexported version takes an operating system argument // primarily to enable the testing package to properly test the function by // forcing an operating system that is not the currently one. func appDataDir(goos, appName string, roaming bool) string { if appName == "" || appName == "." { return "." } // The caller really shouldn't prepend the appName with a period, but // if they do, handle it gracefully by stripping it. if strings.HasPrefix(appName, ".") { appName = appName[1:] } appNameUpper := string(unicode.ToUpper(rune(appName[0]))) + appName[1:] appNameLower := string(unicode.ToLower(rune(appName[0]))) + appName[1:] // Get the OS specific home directory via the Go standard lib. var homeDir string usr, err := user.Current() if err == nil { homeDir = usr.HomeDir } // Fall back to standard HOME environment variable that works // for most POSIX OSes if the directory from the Go standard // lib failed. if err != nil || homeDir == "" { homeDir = os.Getenv("HOME") } switch goos { // Attempt to use the LOCALAPPDATA or APPDATA environment variable on // Windows. case "windows": // Windows XP and before didn't have a LOCALAPPDATA, so fallback // to regular APPDATA when LOCALAPPDATA is not set. appData := os.Getenv("LOCALAPPDATA") if roaming || appData == "" { appData = os.Getenv("APPDATA") } if appData != "" { return filepath.Join(appData, appNameUpper) } case "darwin": if homeDir != "" { return filepath.Join(homeDir, "Library", "Application Support", appNameUpper) } case "plan9": if homeDir != "" { return filepath.Join(homeDir, appNameLower) } default: if homeDir != "" { return filepath.Join(homeDir, "."+appNameLower) } } // Fall back to the current directory if all else fails. return "." } // AppDataDir returns an operating system specific directory to be used for // storing application data for an application. // // The appName parameter is the name of the application the data directory is // being requested for. This function will prepend a period to the appName for // POSIX style operating systems since that is standard practice. An empty // appName or one with a single dot is treated as requesting the current // directory so only "." will be returned. Further, the first character // of appName will be made lowercase for POSIX style operating systems and // uppercase for Mac and Windows since that is standard practice. // // The roaming parameter only applies to Windows where it specifies the roaming // application data profile (%APPDATA%) should be used instead of the local one // (%LOCALAPPDATA%) that is used by default. // // Example results: // dir := AppDataDir("myapp", false) // POSIX (Linux/BSD): ~/.myapp // Mac OS: $HOME/Library/Application Support/Myapp // Windows: %LOCALAPPDATA%\Myapp // Plan 9: $home/myapp func AppDataDir(appName string, roaming bool) string { return appDataDir(runtime.GOOS, appName, roaming) }