mirror of
https://github.com/vbatts/dedupe-linker.git
synced 2025-01-30 17:07:35 +00:00
file: golint
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
e9488b60ff
commit
9a2f27d084
3 changed files with 107 additions and 80 deletions
94
file/dev.go
Normal file
94
file/dev.go
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SameInodePaths checks whether path1 and path2 are the same inode
|
||||||
|
func SameInodePaths(path1, path2 string) (match bool, err error) {
|
||||||
|
var inode1, inode2 uint64
|
||||||
|
if inode1, err = GetInode(path1); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if inode2, err = GetInode(path2); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return inode1 == inode2, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SameDevPaths checks whether path1 and path2 are on the same device
|
||||||
|
func SameDevPaths(path1, path2 string) (match bool, err error) {
|
||||||
|
var dev1, dev2 uint64
|
||||||
|
if dev1, err = GetDev(path1); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if dev2, err = GetDev(path2); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return dev1 == dev2, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatDev has a scary name, but just pretty prints the stat_t.dev as "major:minor"
|
||||||
|
func FormatDev(stat *syscall.Stat_t) string {
|
||||||
|
return fmt.Sprintf("%d:%d", MajorDev(stat.Dev), MinorDev(stat.Dev))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MajorDev provides the major device number from a stat_t.dev
|
||||||
|
func MajorDev(dev uint64) uint64 {
|
||||||
|
return (((dev >> 8) & 0xfff) | ((dev >> 32) & ^uint64(0xfff)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinorDev provides the minor device number from a stat_t.dev
|
||||||
|
func MinorDev(dev uint64) uint64 {
|
||||||
|
return ((dev & 0xff) | ((dev >> 12) & ^uint64(0xff)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLstat returns the system stat_t for the file at path.
|
||||||
|
// (symlinks are not deferenced)
|
||||||
|
func GetLstat(path string) (*syscall.Stat_t, error) {
|
||||||
|
fi, err := os.Lstat(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fi.Sys().(*syscall.Stat_t), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStat returns the system stat_t for the file at path.
|
||||||
|
// (symlinks are deferenced)
|
||||||
|
func GetStat(path string) (*syscall.Stat_t, error) {
|
||||||
|
fi, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fi.Sys().(*syscall.Stat_t), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInode returns the inode for path
|
||||||
|
func GetInode(path string) (uint64, error) {
|
||||||
|
stat, err := GetStat(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return stat.Ino, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDev returns the device for path
|
||||||
|
func GetDev(path string) (uint64, error) {
|
||||||
|
stat, err := GetStat(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return stat.Dev, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNlink returns the number of links for path. For directories, that is
|
||||||
|
// number of entries. For regular files, that is number of hardlinks.
|
||||||
|
func GetNlink(path string) (uint64, error) {
|
||||||
|
stat, err := GetStat(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return stat.Nlink, nil
|
||||||
|
}
|
89
file/hash.go
89
file/hash.go
|
@ -6,11 +6,13 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FileHashInfo struct {
|
// HashInfo for tracking the information regarding a file, it's checksum
|
||||||
|
// and status.
|
||||||
|
// If Err is set then the caller must take an appropriate action.
|
||||||
|
type HashInfo struct {
|
||||||
HashType crypto.Hash
|
HashType crypto.Hash
|
||||||
Hash string
|
Hash string
|
||||||
Path string
|
Path string
|
||||||
|
@ -19,8 +21,10 @@ type FileHashInfo struct {
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func HashFileGetter(path string, hash crypto.Hash, workers int, done <-chan struct{}) <-chan FileHashInfo {
|
// HashFileGetter walks the provided `path` with `workers` number of threads.
|
||||||
out := make(chan FileHashInfo, workers)
|
// The channel of HashInfo are for each regular file encountered.
|
||||||
|
func HashFileGetter(path string, hash crypto.Hash, workers int, done <-chan struct{}) <-chan HashInfo {
|
||||||
|
out := make(chan HashInfo, workers)
|
||||||
go func() {
|
go func() {
|
||||||
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -39,15 +43,15 @@ func HashFileGetter(path string, hash crypto.Hash, workers int, done <-chan stru
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
out <- FileHashInfo{Err: err}
|
out <- HashInfo{Err: err}
|
||||||
}
|
}
|
||||||
close(out)
|
close(out)
|
||||||
}()
|
}()
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashFile(path string, hash crypto.Hash, info os.FileInfo) *FileHashInfo {
|
func hashFile(path string, hash crypto.Hash, info os.FileInfo) *HashInfo {
|
||||||
fhi := FileHashInfo{HashType: hash, Path: path, ModTime: info.ModTime(), Size: info.Size()}
|
fhi := HashInfo{HashType: hash, Path: path, ModTime: info.ModTime(), Size: info.Size()}
|
||||||
h := hash.New()
|
h := hash.New()
|
||||||
fh, err := os.Open(path)
|
fh, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -63,74 +67,3 @@ func hashFile(path string, hash crypto.Hash, info os.FileInfo) *FileHashInfo {
|
||||||
fhi.Hash = fmt.Sprintf("%x", h.Sum(nil))
|
fhi.Hash = fmt.Sprintf("%x", h.Sum(nil))
|
||||||
return &fhi
|
return &fhi
|
||||||
}
|
}
|
||||||
|
|
||||||
// SameInodePaths checks whether path1 and path2 are the same inode
|
|
||||||
func SameInodePaths(path1, path2 string) (match bool, err error) {
|
|
||||||
var inode1, inode2 uint64
|
|
||||||
if inode1, err = GetInode(path1); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if inode2, err = GetInode(path2); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return inode1 == inode2, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SameInodePaths checks whether path1 and path2 are on the same device
|
|
||||||
func SameDevPaths(path1, path2 string) (match bool, err error) {
|
|
||||||
var dev1, dev2 uint64
|
|
||||||
if dev1, err = GetDev(path1); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if dev2, err = GetDev(path2); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return dev1 == dev2, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FormatDev(stat *syscall.Stat_t) string {
|
|
||||||
return fmt.Sprintf("%d:%d", MajorDev(stat.Dev), MinorDev(stat.Dev))
|
|
||||||
}
|
|
||||||
|
|
||||||
func MajorDev(dev uint64) uint64 {
|
|
||||||
return (((dev >> 8) & 0xfff) | ((dev >> 32) & ^uint64(0xfff)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func MinorDev(dev uint64) uint64 {
|
|
||||||
return ((dev & 0xff) | ((dev >> 12) & ^uint64(0xff)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetStat(path string) (*syscall.Stat_t, error) {
|
|
||||||
fi, err := os.Stat(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return fi.Sys().(*syscall.Stat_t), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInode returns the inode for path
|
|
||||||
func GetInode(path string) (uint64, error) {
|
|
||||||
stat, err := GetStat(path)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return stat.Ino, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDev returns the device for path
|
|
||||||
func GetDev(path string) (uint64, error) {
|
|
||||||
stat, err := GetStat(path)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return stat.Dev, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNlink returns the number of links for path
|
|
||||||
func GetNlink(path string) (uint64, error) {
|
|
||||||
stat, err := GetStat(path)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return stat.Nlink, nil
|
|
||||||
}
|
|
||||||
|
|
4
main.go
4
main.go
|
@ -53,8 +53,8 @@ func main() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
hash = cryptomap.DetermineHash(*flCipher)
|
hash = cryptomap.DetermineHash(*flCipher)
|
||||||
//infos = []*file.FileHashInfo{}
|
//infos = []*file.HashInfo{}
|
||||||
//results := make(chan file.FileHashInfo, 2)
|
//results := make(chan file.HashInfo, 2)
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, arg := range flag.Args() {
|
for _, arg := range flag.Args() {
|
||||||
|
|
Loading…
Reference in a new issue