github.com/shivakar/gdupes@v0.0.0-20180726052558-d5c070c306d0/gdupes/filemeta.go (about)

     1  package gdupes
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"syscall"
     7  )
     8  
     9  // getStatStruct returns the syscall.Stat_t struct underlying FileInfo
    10  func getStatStruct(fi os.FileInfo) (*syscall.Stat_t, error) {
    11  	s, ok := fi.Sys().(*syscall.Stat_t)
    12  	if !ok {
    13  		return nil, errors.New("conversion to *syscall.Stat_t failed")
    14  	}
    15  	return s, nil
    16  }
    17  
    18  // FileMeta struct represents metadata for a file
    19  type FileMeta struct {
    20  	Path string
    21  	Info os.FileInfo
    22  }
    23  
    24  // FileMetaSlice represents a FileMeta slice
    25  type FileMetaSlice []FileMeta
    26  
    27  // ContainsInode checks if the inode pointed to by the FileMeta is already
    28  // contained in the FiletMetaSlice
    29  func (f FileMetaSlice) ContainsInode(fm FileMeta) (bool, int, error) {
    30  	s, err := getStatStruct(fm.Info)
    31  	if err != nil {
    32  		return false, -1, err
    33  	}
    34  	if s.Nlink == 1 {
    35  		return false, -1, nil
    36  	}
    37  	inode := s.Ino
    38  	for i, fim := range f {
    39  		s, err := getStatStruct(fim.Info)
    40  		if err != nil {
    41  			return false, -1, err
    42  		}
    43  		if s.Ino == inode {
    44  			return true, i, nil
    45  		}
    46  	}
    47  	return false, -1, nil
    48  }
    49  
    50  // GetFilenames returns the list of filenames
    51  func (f FileMetaSlice) GetFilenames() []string {
    52  	out := make([]string, 0, len(f))
    53  	for _, v := range f {
    54  		out = append(out, v.Path)
    55  	}
    56  	return out
    57  }