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