OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / upgrade.go
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.
4
5 package main
6
7 import (
8         "io"
9         "os"
10         "path/filepath"
11 )
12
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)
16         if err != nil {
17                 return false, err
18         }
19         defer f.Close()
20
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 {
25                 return false, err
26         }
27
28         return len(names) == 0, nil
29 }
30
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")
37         if appData != "" {
38                 return filepath.Join(appData, "btcd")
39         }
40
41         // Fall back to standard HOME directory that works for most POSIX OSes.
42         home := os.Getenv("HOME")
43         if home != "" {
44                 return filepath.Join(home, ".btcd")
45         }
46
47         // In the worst case, use the current directory.
48         return "."
49 }
50
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)
60         if err == nil {
61                 oldDbType := "sqlite"
62                 if fi.IsDir() {
63                         oldDbType = "leveldb"
64                 }
65
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"
72                 }
73                 newDbPath := filepath.Join(newDbRoot, newDbName)
74
75                 // Create the new path if needed.
76                 err = os.MkdirAll(newDbRoot, 0700)
77                 if err != nil {
78                         return err
79                 }
80
81                 // Move and rename the old database.
82                 err := os.Rename(oldDbPath, newDbPath)
83                 if err != nil {
84                         return err
85                 }
86         }
87
88         return nil
89 }
90
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")
102
103         // Remove the old db directory.
104         return os.RemoveAll(oldDbRoot)
105 }
106
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 {
114                 return nil
115         }
116
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)
123                 if err != nil {
124                         return err
125                 }
126
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)
132                         if err != nil {
133                                 return err
134                         }
135                 }
136
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)
142                         if err != nil {
143                                 return err
144                         }
145                 }
146
147                 // Remove the old home if it is empty or show a warning if not.
148                 ohpEmpty, err := dirEmpty(oldHomePath)
149                 if err != nil {
150                         return err
151                 }
152                 if ohpEmpty {
153                         err := os.Remove(oldHomePath)
154                         if err != nil {
155                                 return err
156                         }
157                 } else {
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.",
161                                 oldHomePath)
162                 }
163         }
164
165         return nil
166 }
167
168 // doUpgrades performs upgrades to btcd as new versions require it.
169 func doUpgrades() error {
170         err := upgradeDBPaths()
171         if err != nil {
172                 return err
173         }
174         return upgradeDataPaths()
175 }