summaryrefslogtreecommitdiff
path: root/filesystem.go
diff options
context:
space:
mode:
authorHéctor Orón Martínez <zumbi@debian.org>2018-01-09 19:12:07 +0100
committerHéctor Orón Martínez <zumbi@debian.org>2018-01-09 19:12:07 +0100
commit4808cb7058c548bf76476ec2f9618d784d76bdda (patch)
tree1dc1e8cc24171783fc8d9da306b1e92798960a15 /filesystem.go
New upstream version 1.0.0+git20171222.87b0d5e
Diffstat (limited to 'filesystem.go')
-rw-r--r--filesystem.go105
1 files changed, 105 insertions, 0 deletions
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
+}