mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
f864421ead
This patch updates all dependencies to match what is used in moby/moby. Making the dependencies match what is used in that repository makes sure we test with the same version as libnetwork is later built with in moby. This also gets rid of some temporary forks that were needed during the migration of Sirupsen/logrus to sirupsen/logrus. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
161 lines
3.2 KiB
Go
161 lines
3.2 KiB
Go
package fileutils
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
)
|
|
|
|
// CopyFile copies the file at source to dest
|
|
func CopyFile(source string, dest string) error {
|
|
si, err := os.Lstat(source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
st, ok := si.Sys().(*syscall.Stat_t)
|
|
if !ok {
|
|
return fmt.Errorf("could not convert to syscall.Stat_t")
|
|
}
|
|
|
|
uid := int(st.Uid)
|
|
gid := int(st.Gid)
|
|
|
|
// Handle symlinks
|
|
if si.Mode()&os.ModeSymlink != 0 {
|
|
target, err := os.Readlink(source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := os.Symlink(target, dest); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Handle device files
|
|
if st.Mode&syscall.S_IFMT == syscall.S_IFBLK || st.Mode&syscall.S_IFMT == syscall.S_IFCHR {
|
|
devMajor := int64(major(uint64(st.Rdev)))
|
|
devMinor := int64(minor(uint64(st.Rdev)))
|
|
mode := uint32(si.Mode() & 07777)
|
|
if st.Mode&syscall.S_IFMT == syscall.S_IFBLK {
|
|
mode |= syscall.S_IFBLK
|
|
}
|
|
if st.Mode&syscall.S_IFMT == syscall.S_IFCHR {
|
|
mode |= syscall.S_IFCHR
|
|
}
|
|
if err := syscall.Mknod(dest, mode, int(mkdev(devMajor, devMinor))); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Handle regular files
|
|
if si.Mode().IsRegular() {
|
|
sf, err := os.Open(source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer sf.Close()
|
|
|
|
df, err := os.Create(dest)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer df.Close()
|
|
|
|
_, err = io.Copy(df, sf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Chown the file
|
|
if err := os.Lchown(dest, uid, gid); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Chmod the file
|
|
if !(si.Mode()&os.ModeSymlink == os.ModeSymlink) {
|
|
if err := os.Chmod(dest, si.Mode()); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CopyDirectory copies the files under the source directory
|
|
// to dest directory. The dest directory is created if it
|
|
// does not exist.
|
|
func CopyDirectory(source string, dest string) error {
|
|
fi, err := os.Stat(source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Get owner.
|
|
st, ok := fi.Sys().(*syscall.Stat_t)
|
|
if !ok {
|
|
return fmt.Errorf("could not convert to syscall.Stat_t")
|
|
}
|
|
|
|
// We have to pick an owner here anyway.
|
|
if err := MkdirAllNewAs(dest, fi.Mode(), int(st.Uid), int(st.Gid)); err != nil {
|
|
return err
|
|
}
|
|
|
|
return filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Get the relative path
|
|
relPath, err := filepath.Rel(source, path)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
if info.IsDir() {
|
|
// Skip the source directory.
|
|
if path != source {
|
|
// Get the owner.
|
|
st, ok := info.Sys().(*syscall.Stat_t)
|
|
if !ok {
|
|
return fmt.Errorf("could not convert to syscall.Stat_t")
|
|
}
|
|
|
|
uid := int(st.Uid)
|
|
gid := int(st.Gid)
|
|
|
|
if err := os.Mkdir(filepath.Join(dest, relPath), info.Mode()); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.Lchown(filepath.Join(dest, relPath), uid, gid); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Copy the file.
|
|
if err := CopyFile(path, filepath.Join(dest, relPath)); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func major(device uint64) uint64 {
|
|
return (device >> 8) & 0xfff
|
|
}
|
|
|
|
func minor(device uint64) uint64 {
|
|
return (device & 0xff) | ((device >> 12) & 0xfff00)
|
|
}
|
|
|
|
func mkdev(major int64, minor int64) uint32 {
|
|
return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
|
|
}
|