aboutsummaryrefslogtreecommitdiff
path: root/src/copy.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/copy.go')
-rw-r--r--src/copy.go124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/copy.go b/src/copy.go
new file mode 100644
index 0000000..1076d41
--- /dev/null
+++ b/src/copy.go
@@ -0,0 +1,124 @@
+
+// Package gorecurcopy provides recursive copying in Go (golang) with a
+// minimum of extra packages. Original concept by Oleg Neumyvakin
+// (https://stackoverflow.com/users/1592008/oleg-neumyvakin) and modified
+// by Dirk Avery.
+// Slightly modified by me.
+package main
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ // "syscall"
+)
+
+// copyDir recursively copies a src directory to a destination.
+func copyDir(src, dst string) error {
+ entries, err := ioutil.ReadDir(src)
+ if err != nil {
+ return err
+ }
+ for _, entry := range entries {
+ sourcePath := filepath.Join(src, entry.Name())
+ destPath := filepath.Join(dst, entry.Name())
+
+ fileInfo, err := os.Lstat(sourcePath)
+ if err != nil {
+ return err
+ }
+
+ switch fileInfo.Mode() & os.ModeType {
+ case os.ModeDir:
+ if err := _createDir(destPath, 0755); err != nil {
+ return err
+ }
+ if err := copyDir(sourcePath, destPath); err != nil {
+ return err
+ }
+ case os.ModeSymlink:
+ if err := copySymlink(sourcePath, destPath); err != nil {
+ return err
+ }
+ default:
+ if err := _copy(sourcePath, destPath); err != nil {
+ return err
+ }
+ }
+
+ /*
+ stat, ok := fileInfo.Sys().(*syscall.Stat_t)
+ if !ok {
+ return fmt.Errorf("failed to get raw syscall.Stat_t data for '%s'", sourcePath)
+ }
+ if err := os.Lchown(destPath, int(stat.Uid), int(stat.Gid)); err != nil {
+ return err
+ }
+ */
+
+ isSymlink := entry.Mode()&os.ModeSymlink != 0
+ if !isSymlink {
+ if err := os.Chmod(destPath, entry.Mode()); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// Copy copies a src file to a dst file where src and dst are regular files.
+func _copy(src, dst string) error {
+ sourceFileStat, err := os.Stat(src)
+ if err != nil {
+ return err
+ }
+
+ if !sourceFileStat.Mode().IsRegular() {
+ return fmt.Errorf("%s is not a regular file", src)
+ }
+
+ source, err := os.Open(src)
+ if err != nil {
+ return err
+ }
+ defer source.Close()
+
+ destination, err := os.Create(dst)
+ if err != nil {
+ return err
+ }
+ defer destination.Close()
+ _, err = io.Copy(destination, source)
+ return err
+}
+
+func _exists(path string) bool {
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ return false
+ }
+
+ return true
+}
+
+func _createDir(dir string, perm os.FileMode) error {
+ if _exists(dir) {
+ return nil
+ }
+
+ if err := os.MkdirAll(dir, perm); err != nil {
+ return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error())
+ }
+
+ return nil
+}
+
+// copySymlink copies a symbolic link from src to dst.
+func copySymlink(src, dst string) error {
+ link, err := os.Readlink(src)
+ if err != nil {
+ return err
+ }
+ return os.Symlink(link, dst)
+}