lbcwallet/config.go
Josh Rickmar 310dc010ac Choose correct ports for testnet and mainnet.
This copies the functionality of btcd for choosing the ports for the
HTTP client (for btcd) and server (for frontends).  On testnet, the
following ports are used as default:

 - btcd: 18334
 - frontends: 18332

When running with the (currently disabled) --mainnet flag, btcwallet
will choose the following ports by default:

 - btcd: 8334
 - frontends: 8332

Both ports can be overridden no matter the chosen network using the -b
and -p flags.
2013-10-16 17:29:48 -04:00

171 lines
5.8 KiB
Go

/*
* Copyright (c) 2013 Conformal Systems LLC <info@conformal.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package main
import (
"fmt"
"github.com/conformal/btcwire"
"github.com/conformal/go-flags"
"os"
"path/filepath"
"strings"
)
const (
defaultConfigFilename = "btcwallet.conf"
defaultBtcNet = btcwire.TestNet3
defaultLogLevel = "info"
)
var (
defaultConfigFile = filepath.Join(btcwalletHomeDir(), defaultConfigFilename)
defaultDataDir = btcwalletHomeDir()
)
type config struct {
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
BtcdPort string `short:"b" long:"btcdport" description:"Port to connect to btcd on (default: 18334, mainnet: 18332)"`
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level {trace, debug, info, warn, error, critical}"`
ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"`
SvrPort string `short:"p" long:"serverport" description:"Port to serve frontend websocket connections on (default: 18332, mainnet: 8332)"`
DataDir string `short:"D" long:"datadir" description:"Directory to store wallets and transactions"`
Username string `short:"u" long:"username" description:"Username for btcd authorization"`
Password string `short:"P" long:"password" description:"Password for btcd authorization"`
MainNet bool `long:"mainnet" description:"*DISABLED* Use the main Bitcoin network (default testnet3)"`
}
// btcwalletHomeDir returns an OS appropriate home directory for btcwallet.
func btcwalletHomeDir() string {
// Search for Windows APPDATA first. This won't exist on POSIX OSes.
appData := os.Getenv("APPDATA")
if appData != "" {
return filepath.Join(appData, "btcwallet")
}
// Fall back to standard HOME directory that works for most POSIX OSes.
home := os.Getenv("HOME")
if home != "" {
return filepath.Join(home, ".btcwallet")
}
// In the worst case, use the current directory.
return "."
}
// updateConfigWithActiveParams update the passed config with parameters
// from the active net params if the relevant options in the passed config
// object are the default so options specified by the user on the command line
// are not overridden.
func updateConfigWithActiveParams(cfg *config) {
if cfg.BtcdPort == netParams(defaultBtcNet).btcdPort {
cfg.BtcdPort = activeNetParams.btcdPort
}
if cfg.SvrPort == netParams(defaultBtcNet).svrPort {
cfg.SvrPort = activeNetParams.svrPort
}
}
// filesExists reports whether the named file or directory exists.
func fileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// loadConfig initializes and parses the config using a config file and command
// line options.
//
// The configuration proceeds as follows:
// 1) Start with a default config with sane settings
// 2) Pre-parse the command line to check for an alternative config file
// 3) Load configuration file overwriting defaults with any specified options
// 4) Parse CLI options and overwrite/add any specified options
//
// The above results in btcwallet functioning properly without any config
// settings while still allowing the user to override settings with config files
// and command line options. Command line options always take precedence.
func loadConfig() (*config, []string, error) {
// Default config.
cfg := config{
DebugLevel: defaultLogLevel,
ConfigFile: defaultConfigFile,
BtcdPort: netParams(defaultBtcNet).btcdPort,
SvrPort: netParams(defaultBtcNet).svrPort,
DataDir: defaultDataDir,
}
// A config file in the current directory takes precedence.
if fileExists(defaultConfigFilename) {
cfg.ConfigFile = defaultConfigFile
}
// Pre-parse the command line options to see if an alternative config
// file or the version flag was specified.
preCfg := cfg
preParser := flags.NewParser(&preCfg, flags.Default)
_, err := preParser.Parse()
if err != nil {
if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp {
preParser.WriteHelp(os.Stderr)
}
return nil, nil, err
}
// Show the version and exit if the version flag was specified.
if preCfg.ShowVersion {
appName := filepath.Base(os.Args[0])
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
fmt.Println(appName, "version", version())
os.Exit(0)
}
// Load additional config from file.
parser := flags.NewParser(&cfg, flags.Default)
err = parser.ParseIniFile(preCfg.ConfigFile)
if err != nil {
if _, ok := err.(*os.PathError); !ok {
fmt.Fprintln(os.Stderr, err)
parser.WriteHelp(os.Stderr)
return nil, nil, err
}
log.Warnf("%v", err)
}
// Parse command line options again to ensure they take precedence.
remainingArgs, err := parser.Parse()
if err != nil {
if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp {
parser.WriteHelp(os.Stderr)
}
return nil, nil, err
}
// TODO(jrick): Enable mainnet support again when ready.
cfg.MainNet = false
// Choose the active network params based on the mainnet net flag.
if cfg.MainNet {
activeNetParams = netParams(btcwire.MainNet)
}
updateConfigWithActiveParams(&cfg)
return &cfg, remainingArgs, nil
}