github.com/number571/tendermint@v0.34.11-gost/cmd/tendermint/commands/debug/io.go (about) 1 package debug 2 3 import ( 4 "archive/zip" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "os" 10 "path" 11 "path/filepath" 12 "strings" 13 ) 14 15 // zipDir zips all the contents found in src, including both files and 16 // directories, into a destination file dest. It returns an error upon failure. 17 // It assumes src is a directory. 18 func zipDir(src, dest string) error { 19 zipFile, err := os.Create(dest) 20 if err != nil { 21 return err 22 } 23 defer zipFile.Close() 24 25 zipWriter := zip.NewWriter(zipFile) 26 defer zipWriter.Close() 27 28 dirName := filepath.Base(dest) 29 baseDir := strings.TrimSuffix(dirName, filepath.Ext(dirName)) 30 31 return filepath.Walk(src, func(path string, info os.FileInfo, err error) error { 32 if err != nil { 33 return err 34 } 35 36 header, err := zip.FileInfoHeader(info) 37 if err != nil { 38 return err 39 } 40 41 // Each execution of this utility on a Tendermint process will result in a 42 // unique file. 43 header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, src)) 44 45 // Handle cases where the content to be zipped is a file or a directory, 46 // where a directory must have a '/' suffix. 47 if info.IsDir() { 48 header.Name += "/" 49 } else { 50 header.Method = zip.Deflate 51 } 52 53 headerWriter, err := zipWriter.CreateHeader(header) 54 if err != nil { 55 return err 56 } 57 58 if info.IsDir() { 59 return nil 60 } 61 62 file, err := os.Open(path) 63 if err != nil { 64 return err 65 } 66 defer file.Close() 67 68 _, err = io.Copy(headerWriter, file) 69 return err 70 }) 71 72 } 73 74 // copyFile copies a file from src to dest and returns an error upon failure. The 75 // copied file retains the source file's permissions. 76 func copyFile(src, dest string) error { 77 if _, err := os.Stat(src); os.IsNotExist(err) { 78 return err 79 } 80 81 srcFile, err := os.Open(src) 82 if err != nil { 83 return err 84 } 85 defer srcFile.Close() 86 87 destFile, err := os.Create(dest) 88 if err != nil { 89 return err 90 } 91 defer destFile.Close() 92 93 if _, err = io.Copy(destFile, srcFile); err != nil { 94 return err 95 } 96 97 srcInfo, err := os.Stat(src) 98 if err != nil { 99 return err 100 } 101 102 return os.Chmod(dest, srcInfo.Mode()) 103 } 104 105 // writeStateToFile pretty JSON encodes an object and writes it to file composed 106 // of dir and filename. It returns an error upon failure to encode or write to 107 // file. 108 func writeStateJSONToFile(state interface{}, dir, filename string) error { 109 stateJSON, err := json.MarshalIndent(state, "", " ") 110 if err != nil { 111 return fmt.Errorf("failed to encode state dump: %w", err) 112 } 113 114 return ioutil.WriteFile(path.Join(dir, filename), stateJSON, os.ModePerm) 115 }