diff --git a/CHANGES.md b/CHANGES.md index ccbd4ee8..4b4fc364 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ * The download-speed label now shows a 3 second average. ### Features * trivrost will log the progress of downloads if the connection was interrupted for any reason. +* hasher now supports symlinks within hashed directories. ## 1.4.4 (2020-01-17) ### Changes diff --git a/pkg/launcher/hashing/scan.go b/pkg/launcher/hashing/scan.go index a2d456fa..64092d91 100644 --- a/pkg/launcher/hashing/scan.go +++ b/pkg/launcher/hashing/scan.go @@ -10,6 +10,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "github.com/setlog/trivrost/pkg/launcher/config" log "github.com/sirupsen/logrus" @@ -61,23 +62,29 @@ func mustHashRelatively(ctx context.Context, readDir readDirFunc, readFile readF } func mustHashDir(ctx context.Context, readDir readDirFunc, readFile readFileFunc, stat statFunc, hashFilePath string) config.FileInfoMap { - fm := make(config.FileInfoMap) - for _, info := range mustReadDir(readDir, hashFilePath) { - if info.IsDir() { - fm.Join(mustHashDir(ctx, readDir, readFile, stat, filepath.Join(hashFilePath, info.Name()))) - } else { - filePath := filepath.Join(hashFilePath, info.Name()) - if isDir(filePath) { - fm.Join(mustHashDir(readDir, readFile, stat, filePath)) + fileMap := make(config.FileInfoMap) + for _, curPathInfo := range mustReadDir(readDir, hashFilePath) { + curPath := filepath.Join(hashFilePath, curPathInfo.Name()) + resolvedPath := evaluateSoftLink(curPath) + if curPath != resolvedPath { + log.Warnf("File \"%s\"->\"%s\" is a symlink, will be treated as a regular file/dir.", curPath, resolvedPath) + curPath = resolvedPath + } + if !strings.HasPrefix(curPath, hashFilePath) { + panic(fmt.Errorf("hashing '%s' outside hash directory is not allowed", curPath)) + } + curPathInfo, _ = stat(curPath) + if curPathInfo.IsDir() { + fileMap.Join(mustHashDir(ctx, readDir, readFile, stat, curPath)) } else { - sha, size, err := calculateSha256(ctx, filePath, readFile) + sha, size, err := calculateSha256(ctx, curPath, readFile) if err != nil { panic(fmt.Errorf("failed hashing file \"%s\": %w", hashFilePath, err)) } - fm[filePath] = &config.FileInfo{SHA256: sha, Size: size} + fileMap[curPath] = &config.FileInfo{SHA256: sha, Size: size} } } - return fm + return fileMap } func evaluateSoftLink(filePath string) string { @@ -88,14 +95,6 @@ func evaluateSoftLink(filePath string) string { return evaluatedName } -func isDir(filePath string) bool { - fi, err := os.Stat(filePath) - if err != nil { - panic(err) - } - return fi.IsDir() -} - func mustReadDir(readDir readDirFunc, directoryPath string) []os.FileInfo { infos, err := readDir(evaluateSoftLink(directoryPath)) if err != nil {