From 4808cb7058c548bf76476ec2f9618d784d76bdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Or=C3=B3n=20Mart=C3=ADnez?= Date: Tue, 9 Jan 2018 19:12:07 +0100 Subject: New upstream version 1.0.0+git20171222.87b0d5e --- filesystem.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 filesystem.go (limited to 'filesystem.go') diff --git a/filesystem.go b/filesystem.go new file mode 100644 index 0000000..a6e5239 --- /dev/null +++ b/filesystem.go @@ -0,0 +1,105 @@ +package debos + +import ( + "fmt" + "io" + "io/ioutil" + "log" + "os" + "path" + "path/filepath" + "strings" +) + +func CleanPathAt(path, at string) string { + if filepath.IsAbs(path) { + return filepath.Clean(path) + } + + return filepath.Join(at, path) +} + +func CleanPath(path string) string { + cwd, _ := os.Getwd() + return CleanPathAt(path, cwd) +} + +func CopyFile(src, dst string, mode os.FileMode) error { + in, err := os.Open(src) + if err != nil { + return err + } + defer in.Close() + tmp, err := ioutil.TempFile(filepath.Dir(dst), "") + if err != nil { + return err + } + _, err = io.Copy(tmp, in) + if err != nil { + tmp.Close() + os.Remove(tmp.Name()) + return err + } + if err = tmp.Close(); err != nil { + os.Remove(tmp.Name()) + return err + } + if err = os.Chmod(tmp.Name(), mode); err != nil { + os.Remove(tmp.Name()) + return err + } + return os.Rename(tmp.Name(), dst) +} + +func CopyTree(sourcetree, desttree string) error { + fmt.Printf("Overlaying %s on %s\n", sourcetree, desttree) + walker := func(p string, info os.FileInfo, err error) error { + + if err != nil { + return err + } + + suffix, _ := filepath.Rel(sourcetree, p) + target := path.Join(desttree, suffix) + switch info.Mode() & os.ModeType { + case 0: + CopyFile(p, target, info.Mode()) + case os.ModeDir: + os.Mkdir(target, info.Mode()) + case os.ModeSymlink: + link, err := os.Readlink(p) + if err != nil { + log.Panicf("Failed to read symlink %s: %v", suffix, err) + } + os.Symlink(link, target) + default: + log.Panicf("Not handled /%s %v", suffix, info.Mode()) + } + + return nil + } + + return filepath.Walk(sourcetree, walker) +} + +func RealPath(path string) (string, error) { + p, err := filepath.EvalSymlinks(path) + if err != nil { + return "", err + } + + return filepath.Abs(p) +} + +func RestrictedPath(prefix, dest string) (string, error) { + var err error + destination := path.Join(prefix, dest) + destination, err = filepath.Abs(destination) + if err != nil { + return "", err + } + if !strings.HasPrefix(destination, prefix) { + return "", fmt.Errorf("The resulting path points outside of prefix '%s': '%s'\n", prefix, destination) + } + return destination, nil +} -- cgit v1.2.3