123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /*
- * Rufs - Remote Union File System
- *
- * Copyright 2017 Matthias Ladkau. All rights reserved.
- *
- * This Source Code Form is subject to the terms of the MIT
- * License, If a copy of the MIT License was not distributed with this
- * file, You can obtain one at https://opensource.org/licenses/MIT.
- */
- package rufs
- import (
- "fmt"
- "os"
- "path/filepath"
- "time"
- )
- /*
- Special unit test flag - use a common mode to gloss over OS specific
- defaults
- */
- var unitTestModes = false
- /*
- FileInfo implements os.FileInfo in an platform-agnostic way
- */
- type FileInfo struct {
- FiName string // Base name
- FiSize int64 // Size in bytes
- FiMode os.FileMode // File mode bits
- FiModTime time.Time // Modification time
- FiChecksum string // Checksum of files
- // Private fields which will not be transferred via RPC
- isSymLink bool // Flag if this is a symlink (unix)
- symLinkTarget string // Target file/directory of the symlink
- }
- /*
- WrapFileInfo wraps a single os.FileInfo object in a serializable FileInfo.
- */
- func WrapFileInfo(path string, i os.FileInfo) os.FileInfo {
- var realPath string
- // Check if we have a symlink
- mode := i.Mode()
- size := i.Size()
- isSymlink := i.Mode()&os.ModeSymlink != 0
- if isSymlink {
- var err error
- if realPath, err = filepath.EvalSymlinks(filepath.Join(path, i.Name())); err == nil {
- var ri os.FileInfo
- if ri, err = os.Stat(realPath); err == nil {
- // Write in the size of the target and file mode
- mode = ri.Mode()
- size = ri.Size()
- }
- }
- }
- // Unit test fixed file modes
- if unitTestModes {
- mode = mode & os.ModeDir
- if mode.IsDir() {
- mode = mode | 0777
- size = 4096
- } else {
- mode = mode | 0666
- }
- }
- return &FileInfo{i.Name(), size, mode, i.ModTime(), "",
- isSymlink, realPath}
- }
- /*
- WrapFileInfos wraps a list of os.FileInfo objects into a list of
- serializable FileInfo objects. This function will modify the given
- list.
- */
- func WrapFileInfos(path string, is []os.FileInfo) []os.FileInfo {
- for i, info := range is {
- is[i] = WrapFileInfo(path, info)
- }
- return is
- }
- /*
- Name returns the base name.
- */
- func (rfi *FileInfo) Name() string {
- return rfi.FiName
- }
- /*
- Size returns the length in bytes.
- */
- func (rfi *FileInfo) Size() int64 {
- return rfi.FiSize
- }
- /*
- Mode returns the file mode bits.
- */
- func (rfi *FileInfo) Mode() os.FileMode {
- return rfi.FiMode
- }
- /*
- ModTime returns the modification time.
- */
- func (rfi *FileInfo) ModTime() time.Time {
- return rfi.FiModTime
- }
- /*
- Checksum returns the checksum of this file. May be an empty string if it was
- not calculated.
- */
- func (rfi *FileInfo) Checksum() string {
- return rfi.FiChecksum
- }
- /*
- IsDir returns if this is a directory.
- */
- func (rfi *FileInfo) IsDir() bool {
- return rfi.FiMode.IsDir()
- }
- /*
- Sys should return the underlying data source but will always return nil
- for FileInfo nodes.
- */
- func (rfi *FileInfo) Sys() interface{} {
- return nil
- }
- func (rfi *FileInfo) String() string {
- sum := rfi.Checksum()
- if sum != "" {
- return fmt.Sprintf("%v %s [%v] %v (%v) - %v", rfi.Name(), sum, rfi.Size(),
- rfi.Mode(), rfi.ModTime(), rfi.Sys())
- }
- return fmt.Sprintf("%v [%v] %v (%v) - %v", rfi.Name(), rfi.Size(),
- rfi.Mode(), rfi.ModTime(), rfi.Sys())
- }
|