github.com/pkg/sftp@v1.13.6/stat_plan9.go (about)

     1  package sftp
     2  
     3  import (
     4  	"os"
     5  	"syscall"
     6  )
     7  
     8  var EBADF = syscall.NewError("fd out of range or not open")
     9  
    10  func wrapPathError(filepath string, err error) error {
    11  	if errno, ok := err.(syscall.ErrorString); ok {
    12  		return &os.PathError{Path: filepath, Err: errno}
    13  	}
    14  	return err
    15  }
    16  
    17  // translateErrno translates a syscall error number to a SFTP error code.
    18  func translateErrno(errno syscall.ErrorString) uint32 {
    19  	switch errno {
    20  	case "":
    21  		return sshFxOk
    22  	case syscall.ENOENT:
    23  		return sshFxNoSuchFile
    24  	case syscall.EPERM:
    25  		return sshFxPermissionDenied
    26  	}
    27  
    28  	return sshFxFailure
    29  }
    30  
    31  func translateSyscallError(err error) (uint32, bool) {
    32  	switch e := err.(type) {
    33  	case syscall.ErrorString:
    34  		return translateErrno(e), true
    35  	case *os.PathError:
    36  		debug("statusFromError,pathError: error is %T %#v", e.Err, e.Err)
    37  		if errno, ok := e.Err.(syscall.ErrorString); ok {
    38  			return translateErrno(errno), true
    39  		}
    40  	}
    41  	return 0, false
    42  }
    43  
    44  // isRegular returns true if the mode describes a regular file.
    45  func isRegular(mode uint32) bool {
    46  	return mode&S_IFMT == syscall.S_IFREG
    47  }
    48  
    49  // toFileMode converts sftp filemode bits to the os.FileMode specification
    50  func toFileMode(mode uint32) os.FileMode {
    51  	var fm = os.FileMode(mode & 0777)
    52  
    53  	switch mode & S_IFMT {
    54  	case syscall.S_IFBLK:
    55  		fm |= os.ModeDevice
    56  	case syscall.S_IFCHR:
    57  		fm |= os.ModeDevice | os.ModeCharDevice
    58  	case syscall.S_IFDIR:
    59  		fm |= os.ModeDir
    60  	case syscall.S_IFIFO:
    61  		fm |= os.ModeNamedPipe
    62  	case syscall.S_IFLNK:
    63  		fm |= os.ModeSymlink
    64  	case syscall.S_IFREG:
    65  		// nothing to do
    66  	case syscall.S_IFSOCK:
    67  		fm |= os.ModeSocket
    68  	}
    69  
    70  	return fm
    71  }
    72  
    73  // fromFileMode converts from the os.FileMode specification to sftp filemode bits
    74  func fromFileMode(mode os.FileMode) uint32 {
    75  	ret := uint32(mode & os.ModePerm)
    76  
    77  	switch mode & os.ModeType {
    78  	case os.ModeDevice | os.ModeCharDevice:
    79  		ret |= syscall.S_IFCHR
    80  	case os.ModeDevice:
    81  		ret |= syscall.S_IFBLK
    82  	case os.ModeDir:
    83  		ret |= syscall.S_IFDIR
    84  	case os.ModeNamedPipe:
    85  		ret |= syscall.S_IFIFO
    86  	case os.ModeSymlink:
    87  		ret |= syscall.S_IFLNK
    88  	case 0:
    89  		ret |= syscall.S_IFREG
    90  	case os.ModeSocket:
    91  		ret |= syscall.S_IFSOCK
    92  	}
    93  
    94  	return ret
    95  }
    96  
    97  // Plan 9 doesn't have setuid, setgid or sticky, but a Plan 9 client should
    98  // be able to send these bits to a POSIX server.
    99  const (
   100  	s_ISUID = 04000
   101  	s_ISGID = 02000
   102  	s_ISVTX = 01000
   103  )