1 // Copyright (c) 2013-2014 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
13 // dirEmpty returns whether or not the specified directory path is empty.
14 func dirEmpty(dirPath string) (bool, error) {
15 f, err := os.Open(dirPath)
21 // Read the names of a max of one entry from the directory. When the
22 // directory is empty, an io.EOF error will be returned, so allow it.
23 names, err := f.Readdirnames(1)
24 if err != nil && err != io.EOF {
28 return len(names) == 0, nil
31 // oldBtcdHomeDir returns the OS specific home directory btcd used prior to
32 // version 0.3.3. This has since been replaced with btcutil.AppDataDir, but
33 // this function is still provided for the automatic upgrade path.
34 func oldBtcdHomeDir() string {
35 // Search for Windows APPDATA first. This won't exist on POSIX OSes.
36 appData := os.Getenv("APPDATA")
38 return filepath.Join(appData, "btcd")
41 // Fall back to standard HOME directory that works for most POSIX OSes.
42 home := os.Getenv("HOME")
44 return filepath.Join(home, ".btcd")
47 // In the worst case, use the current directory.
51 // upgradeDBPathNet moves the database for a specific network from its
52 // location prior to btcd version 0.2.0 and uses heuristics to ascertain the old
53 // database type to rename to the new format.
54 func upgradeDBPathNet(oldDbPath, netName string) error {
55 // Prior to version 0.2.0, the database was named the same thing for
56 // both sqlite and leveldb. Use heuristics to figure out the type
57 // of the database and move it to the new path and name introduced with
58 // version 0.2.0 accordingly.
59 fi, err := os.Stat(oldDbPath)
66 // The new database name is based on the database type and
67 // resides in a directory named after the network type.
68 newDbRoot := filepath.Join(filepath.Dir(cfg.DataDir), netName)
69 newDbName := blockDbNamePrefix + "_" + oldDbType
70 if oldDbType == "sqlite" {
71 newDbName = newDbName + ".db"
73 newDbPath := filepath.Join(newDbRoot, newDbName)
75 // Create the new path if needed.
76 err = os.MkdirAll(newDbRoot, 0700)
81 // Move and rename the old database.
82 err := os.Rename(oldDbPath, newDbPath)
91 // upgradeDBPaths moves the databases from their locations prior to btcd
92 // version 0.2.0 to their new locations.
93 func upgradeDBPaths() error {
94 // Prior to version 0.2.0, the databases were in the "db" directory and
95 // their names were suffixed by "testnet" and "regtest" for their
96 // respective networks. Check for the old database and update it to the
97 // new path introduced with version 0.2.0 accordingly.
98 oldDbRoot := filepath.Join(oldBtcdHomeDir(), "db")
99 upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd.db"), "mainnet")
100 upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_testnet.db"), "testnet")
101 upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_regtest.db"), "regtest")
103 // Remove the old db directory.
104 return os.RemoveAll(oldDbRoot)
107 // upgradeDataPaths moves the application data from its location prior to btcd
108 // version 0.3.3 to its new location.
109 func upgradeDataPaths() error {
110 // No need to migrate if the old and new home paths are the same.
111 oldHomePath := oldBtcdHomeDir()
112 newHomePath := defaultHomeDir
113 if oldHomePath == newHomePath {
117 // Only migrate if the old path exists and the new one doesn't.
118 if fileExists(oldHomePath) && !fileExists(newHomePath) {
119 // Create the new path.
120 btcdLog.Infof("Migrating application home path from '%s' to '%s'",
121 oldHomePath, newHomePath)
122 err := os.MkdirAll(newHomePath, 0700)
127 // Move old btcd.conf into new location if needed.
128 oldConfPath := filepath.Join(oldHomePath, defaultConfigFilename)
129 newConfPath := filepath.Join(newHomePath, defaultConfigFilename)
130 if fileExists(oldConfPath) && !fileExists(newConfPath) {
131 err := os.Rename(oldConfPath, newConfPath)
137 // Move old data directory into new location if needed.
138 oldDataPath := filepath.Join(oldHomePath, defaultDataDirname)
139 newDataPath := filepath.Join(newHomePath, defaultDataDirname)
140 if fileExists(oldDataPath) && !fileExists(newDataPath) {
141 err := os.Rename(oldDataPath, newDataPath)
147 // Remove the old home if it is empty or show a warning if not.
148 ohpEmpty, err := dirEmpty(oldHomePath)
153 err := os.Remove(oldHomePath)
158 btcdLog.Warnf("Not removing '%s' since it contains files "+
159 "not created by this application. You may "+
160 "want to manually move them or delete them.",
168 // doUpgrades performs upgrades to btcd as new versions require it.
169 func doUpgrades() error {
170 err := upgradeDBPaths()
174 return upgradeDataPaths()